File indexing completed on 2024-05-12 03:54:30
0001 /* 0002 This file is part of the KDE libraries. 0003 0004 SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org> 0005 SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org> 0006 SPDX-FileCopyrightText: 2003 Zack Rusin <zack@kde.org> 0007 SPDX-FileCopyrightText: 2006 MichaĆ«l Larouche <michael.larouche@kdemail.net> 0008 SPDX-FileCopyrightText: 2008 Allen Winter <winter@kde.org> 0009 SPDX-FileCopyrightText: 2020 Tomaz Cananbrava <tcanabrava@kde.org> 0010 0011 SPDX-License-Identifier: LGPL-2.0-or-later 0012 */ 0013 0014 #include "KConfigHeaderGenerator.h" 0015 0016 #include <QDebug> 0017 #include <QTextStream> 0018 #include <iostream> 0019 0020 KConfigHeaderGenerator::KConfigHeaderGenerator(const QString &inputFile, const QString &baseDir, const KConfigParameters &cfg, ParseResult &result) 0021 : KConfigCodeGeneratorBase(inputFile, baseDir, baseDir + cfg.baseName + QLatin1Char('.') + cfg.headerExtension, cfg, result) 0022 { 0023 } 0024 0025 void KConfigHeaderGenerator::start() 0026 { 0027 KConfigCodeGeneratorBase::start(); 0028 startHeaderGuards(); 0029 createHeaders(); 0030 0031 beginNamespaces(); 0032 0033 createForwardDeclarations(); 0034 0035 doClassDefinition(); 0036 0037 endNamespaces(); 0038 endHeaderGuards(); 0039 } 0040 0041 void KConfigHeaderGenerator::doClassDefinition() 0042 { 0043 stream() << "class " << cfg().visibility << cfg().className << " : public " << cfg().inherits << '\n'; 0044 startScope(); 0045 0046 // Add Q_OBJECT macro if the config need signals. 0047 if (!parseResult.signalList.isEmpty() || cfg().generateProperties) { 0048 stream() << " Q_OBJECT\n"; 0049 } 0050 stream() << " public:\n"; 0051 implementEnums(); 0052 createConstructor(); 0053 createDestructor(); 0054 0055 for (const auto *entry : std::as_const(parseResult.entries)) { 0056 const QString returnType = (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) ? enumType(entry, cfg().globalEnums) : cppType(entry->type); 0057 0058 createSetters(entry); 0059 createProperties(entry, returnType); 0060 createImmutableProperty(entry); 0061 createGetters(entry, returnType); 0062 createImmutableGetters(entry); 0063 createDefaultValueMember(entry); 0064 createItemAcessors(entry, returnType); 0065 } 0066 0067 createSignals(); 0068 stream() << " protected:\n"; 0069 createSingleton(); 0070 0071 // TODO: Move those to functions too. 0072 if (parseResult.hasNonModifySignals) { 0073 stream() << whitespace() << "bool usrSave() override;\n"; 0074 } 0075 0076 // Member variables 0077 if (!cfg().memberVariables.isEmpty() // 0078 && cfg().memberVariables != QLatin1String("private") // 0079 && cfg().memberVariables != QLatin1String("dpointer")) { 0080 stream() << " " << cfg().memberVariables << ":\n"; 0081 } 0082 0083 // Class Parameters 0084 for (const auto ¶meter : std::as_const(parseResult.parameters)) { 0085 stream() << whitespace() << "" << cppType(parameter.type) << " mParam" << parameter.name << ";\n"; 0086 } 0087 0088 createNonDPointerHelpers(); 0089 createDPointer(); 0090 0091 if (cfg().customAddons) { 0092 stream() << whitespace() << "// Include custom additions\n"; 0093 stream() << whitespace() << "#include \"" << cfg().baseName << "_addons." << cfg().headerExtension << "\"\n"; 0094 } 0095 0096 endScope(ScopeFinalizer::Semicolon); 0097 } 0098 0099 void KConfigHeaderGenerator::createHeaders() 0100 { 0101 addHeaders(cfg().headerIncludes); 0102 if (cfg().headerIncludes.size()) { 0103 stream() << '\n'; 0104 } 0105 0106 if (!cfg().singleton && parseResult.parameters.isEmpty()) { 0107 addHeaders({QStringLiteral("qglobal.h")}); 0108 } 0109 0110 if (cfg().inherits == QLatin1String("KCoreConfigSkeleton")) { 0111 addHeaders({QStringLiteral("kcoreconfigskeleton.h")}); 0112 } else { 0113 addHeaders({QStringLiteral("kconfigskeleton.h")}); 0114 } 0115 0116 addHeaders({QStringLiteral("QCoreApplication"), QStringLiteral("QDebug")}); 0117 if (!cfg().dpointer && parseResult.hasNonModifySignals) { 0118 addHeaders({QStringLiteral("QSet")}); 0119 } 0120 stream() << '\n'; 0121 0122 addHeaders(parseResult.includes); 0123 if (parseResult.includes.size()) { 0124 stream() << '\n'; 0125 } 0126 } 0127 0128 void KConfigHeaderGenerator::startHeaderGuards() 0129 { 0130 const bool hasNamespace = !cfg().nameSpace.isEmpty(); 0131 const QString namespaceName = QString(QString(cfg().nameSpace).replace(QLatin1String("::"), QLatin1String("_"))).toUpper(); 0132 const QString namespaceStr = hasNamespace ? namespaceName + QLatin1Char('_') : QString{}; 0133 const QString defineName = namespaceStr + cfg().className.toUpper() + QStringLiteral("_H"); 0134 0135 stream() << "#ifndef " << defineName << '\n'; 0136 stream() << "#define " << defineName << '\n'; 0137 stream() << '\n'; 0138 } 0139 0140 void KConfigHeaderGenerator::endHeaderGuards() 0141 { 0142 stream() << '\n'; 0143 stream() << "#endif"; 0144 stream() << '\n'; 0145 // HACK: Original files ended with two last newlines, add them. 0146 stream() << '\n'; 0147 } 0148 0149 void KConfigHeaderGenerator::implementChoiceEnums(const CfgEntry *entry, const CfgEntry::Choices &choices) 0150 { 0151 const QList<CfgEntry::Choice> chlist = choices.choices; 0152 0153 if (chlist.isEmpty()) { 0154 return; 0155 } 0156 0157 QStringList values; 0158 for (const auto &choice : std::as_const(chlist)) { 0159 values.append(choices.prefix + choice.name); 0160 } 0161 0162 if (choices.name().isEmpty()) { 0163 if (cfg().globalEnums) { 0164 stream() << whitespace() << "enum " << enumName(entry->name, entry->choices) << " { " << values.join(QStringLiteral(", ")) << " };\n"; 0165 if (cfg().generateProperties) { 0166 stream() << whitespace() << "Q_ENUM(" << enumName(entry->name, entry->choices) << ")\n"; 0167 } 0168 } else { 0169 // Create an automatically named enum 0170 stream() << whitespace() << "class " << enumName(entry->name, entry->choices) << '\n'; 0171 stream() << whitespace() << "{\n"; 0172 stream() << whitespace() << " public:\n"; 0173 stream() << whitespace() << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };\n"; 0174 stream() << whitespace() << "};\n"; 0175 } 0176 } else if (!choices.external()) { 0177 // Create a named enum 0178 stream() << whitespace() << "enum " << enumName(entry->name, entry->choices) << " { " << values.join(QStringLiteral(", ")) << " };\n"; 0179 } 0180 } 0181 0182 void KConfigHeaderGenerator::implementValueEnums(const CfgEntry *entry, const QStringList &values) 0183 { 0184 if (values.isEmpty()) { 0185 return; 0186 } 0187 0188 if (cfg().globalEnums) { 0189 // ### FIXME!! 0190 // make the following string table an index-based string search! 0191 // ### 0192 stream() << whitespace() << "enum " << enumName(entry->param) << " { " << values.join(QStringLiteral(", ")) << " };\n"; 0193 stream() << whitespace() << "static const char* const " << enumName(entry->param) << "ToString[];\n"; 0194 } else { 0195 stream() << whitespace() << "class " << enumName(entry->param) << '\n'; 0196 stream() << whitespace() << "{\n"; 0197 stream() << whitespace() << " public:\n"; 0198 stream() << whitespace() << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };\n"; 0199 stream() << whitespace() << " static const char* const enumToString[];\n"; 0200 stream() << whitespace() << "};\n"; 0201 } 0202 } 0203 0204 void KConfigHeaderGenerator::implementEnums() 0205 { 0206 if (!parseResult.entries.size()) { 0207 return; 0208 } 0209 0210 for (const auto *entry : std::as_const(parseResult.entries)) { 0211 const CfgEntry::Choices &choices = entry->choices; 0212 const QStringList values = entry->paramValues; 0213 0214 implementChoiceEnums(entry, choices); 0215 implementValueEnums(entry, values); 0216 } 0217 stream() << '\n'; 0218 } 0219 0220 void KConfigHeaderGenerator::createSignals() 0221 { 0222 // Signal definition. 0223 if (parseResult.signalList.isEmpty()) { 0224 return; 0225 } 0226 0227 stream() << "\n enum {\n"; 0228 0229 // HACK: Use C-Style for add a comma in all but the last element, 0230 // just to make the source generated code equal to the old one. 0231 // When we are sure, revert this to a range-based-for and just add 0232 // a last comma, as it's valid c++. 0233 for (int i = 0, end = parseResult.signalList.size(); i < end; i++) { 0234 auto signal = parseResult.signalList.at(i); 0235 stream() << whitespace() << " " << signalEnumName(signal.name) << " = " << (i + 1); 0236 if (i != end - 1) { 0237 stream() << ",\n"; 0238 } 0239 } 0240 stream() << '\n'; 0241 stream() << whitespace() << "};\n\n"; 0242 0243 stream() << " Q_SIGNALS:"; 0244 for (const Signal &signal : std::as_const(parseResult.signalList)) { 0245 stream() << '\n'; 0246 if (!signal.label.isEmpty()) { 0247 stream() << whitespace() << "/**\n"; 0248 stream() << whitespace() << " " << signal.label << '\n'; 0249 stream() << whitespace() << "*/\n"; 0250 } 0251 stream() << whitespace() << "void " << signal.name << "("; 0252 0253 auto it = signal.arguments.cbegin(); 0254 const auto itEnd = signal.arguments.cend(); 0255 while (it != itEnd) { 0256 Param argument = *it; 0257 QString type = param(argument.type); 0258 if (cfg().useEnumTypes && argument.type == QLatin1String("Enum")) { 0259 for (const auto *entry : std::as_const(parseResult.entries)) { 0260 if (entry->name == argument.name) { 0261 type = enumType(entry, cfg().globalEnums); 0262 break; 0263 } 0264 } 0265 } 0266 stream() << type << " " << argument.name; 0267 if (++it != itEnd) { 0268 stream() << ", "; 0269 } 0270 } 0271 stream() << ");\n"; 0272 } 0273 stream() << '\n'; 0274 0275 stream() << " private:\n"; 0276 stream() << whitespace() << "void itemChanged(quint64 signalFlag);\n"; 0277 stream() << '\n'; 0278 } 0279 0280 void KConfigHeaderGenerator::createDPointer() 0281 { 0282 if (!cfg().dpointer) { 0283 return; 0284 } 0285 0286 // use a private class for both member variables and items 0287 stream() << " private:\n"; 0288 for (const auto *entry : std::as_const(parseResult.entries)) { 0289 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) { 0290 stream() << whitespace() << ""; 0291 if (cfg().staticAccessors) { 0292 stream() << "static "; 0293 } 0294 stream() << cppType(entry->type) << " " << getDefaultFunction(entry->name) << "_helper("; 0295 if (!entry->param.isEmpty()) { 0296 stream() << " " << cppType(entry->paramType) << " i "; 0297 } 0298 stream() << ")" << Const() << ";\n"; 0299 } 0300 } 0301 stream() << whitespace() << "" << cfg().className << "Private *d;\n"; 0302 } 0303 0304 void KConfigHeaderGenerator::createConstructor() 0305 { 0306 if (cfg().singleton) { 0307 stream() << whitespace() << "static " << cfg().className << " *self();\n"; 0308 if (parseResult.cfgFileNameArg) { 0309 stream() << whitespace() << "static void instance(const QString& cfgfilename);\n"; 0310 stream() << whitespace() << "static void instance(KSharedConfig::Ptr config);\n"; 0311 } 0312 return; 0313 } 0314 0315 stream() << whitespace() << "" << cfg().className << "("; 0316 if (parseResult.cfgFileNameArg) { 0317 if (cfg().forceStringFilename) { 0318 stream() << " const QString &cfgfilename" << (parseResult.parameters.isEmpty() ? " = QString()" : ", "); 0319 } else if (parseResult.cfgStateConfig) { 0320 stream() << " KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ? " = KSharedConfig::openStateConfig()" : ", "); 0321 } else { 0322 stream() << " KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", "); 0323 } 0324 } 0325 if (cfg().forceStringFilename && parseResult.cfgStateConfig) { 0326 std::cerr << "One can not use ForceStringFilename and use the stateConfig attribute, consider " 0327 "removing the ForceStringFilename kcfgc option if you want to use state data" 0328 << std::endl; 0329 } 0330 0331 bool first = true; 0332 for (const auto ¶meter : std::as_const(parseResult.parameters)) { 0333 if (first) { 0334 first = false; 0335 } else { 0336 stream() << ","; 0337 } 0338 0339 stream() << " " << param(parameter.type) << " " << parameter.name; 0340 } 0341 0342 if (cfg().parentInConstructor) { 0343 if (parseResult.cfgFileNameArg || !parseResult.parameters.isEmpty()) { 0344 stream() << ","; 0345 } 0346 stream() << " QObject *parent = nullptr"; 0347 } 0348 stream() << " );\n"; 0349 } 0350 0351 void KConfigHeaderGenerator::createDestructor() 0352 { 0353 stream() << whitespace() << "~" << cfg().className << "() override;\n\n"; 0354 } 0355 0356 void KConfigHeaderGenerator::createForwardDeclarations() 0357 { 0358 // Private class declaration 0359 if (cfg().dpointer) { 0360 stream() << "class " << cfg().className << "Private;\n\n"; 0361 } 0362 } 0363 0364 void KConfigHeaderGenerator::createProperties(const CfgEntry *entry, const QString &returnType) 0365 { 0366 if (!cfg().generateProperties) { 0367 return; 0368 } 0369 stream() << whitespace() << "Q_PROPERTY(" << returnType << ' ' << getFunction(entry->name); 0370 stream() << " READ " << getFunction(entry->name); 0371 0372 if (cfg().allMutators || cfg().mutators.contains(entry->name)) { 0373 const QString signal = changeSignalName(entry->name); 0374 stream() << " WRITE " << setFunction(entry->name); 0375 stream() << " NOTIFY " << signal; 0376 0377 // If we have the modified signal, we'll also need 0378 // the changed signal as well 0379 Signal s; 0380 s.name = signal; 0381 s.modify = true; 0382 parseResult.signalList.append(s); 0383 } else { 0384 stream() << " CONSTANT"; 0385 } 0386 stream() << ")\n"; 0387 } 0388 0389 void KConfigHeaderGenerator::createImmutableProperty(const CfgEntry *entry) 0390 { 0391 if (!cfg().generateProperties) { 0392 return; 0393 } 0394 stream() << whitespace(); 0395 stream() << "Q_PROPERTY(bool " << immutableFunction(entry->name); 0396 stream() << " READ " << immutableFunction(entry->name); 0397 stream() << " CONSTANT)\n"; 0398 } 0399 0400 void KConfigHeaderGenerator::createSetters(const CfgEntry *entry) 0401 { 0402 // Manipulator 0403 if (!cfg().allMutators && !cfg().mutators.contains(entry->name)) { 0404 return; 0405 } 0406 0407 stream() << whitespace() << "/**\n"; 0408 stream() << whitespace() << " Set " << entry->label << '\n'; 0409 stream() << whitespace() << "*/\n"; 0410 0411 if (cfg().staticAccessors) { 0412 stream() << whitespace() << "static\n"; 0413 } 0414 0415 stream() << whitespace() << "void " << setFunction(entry->name) << "( "; 0416 if (!entry->param.isEmpty()) { 0417 stream() << cppType(entry->paramType) << " i, "; 0418 } 0419 0420 stream() << (cfg().useEnumTypes && entry->type == QLatin1String("Enum") ? enumType(entry, cfg().globalEnums) : param(entry->type)); 0421 0422 stream() << " v )"; 0423 0424 // function body inline only if not using dpointer 0425 // for BC mode 0426 if (!cfg().dpointer) { 0427 stream() << '\n'; 0428 startScope(); 0429 memberMutatorBody(entry); 0430 endScope(); 0431 stream() << '\n'; 0432 } else { 0433 stream() << ";\n\n"; 0434 } 0435 } 0436 0437 void KConfigHeaderGenerator::createGetters(const CfgEntry *entry, const QString &returnType) 0438 { 0439 // Accessor 0440 stream() << whitespace() << "/**\n"; 0441 stream() << whitespace() << " Get " << entry->label << '\n'; 0442 stream() << whitespace() << "*/\n"; 0443 if (cfg().staticAccessors) { 0444 stream() << whitespace() << "static\n"; 0445 } 0446 stream() << whitespace() << ""; 0447 stream() << returnType; 0448 stream() << " " << getFunction(entry->name) << "("; 0449 if (!entry->param.isEmpty()) { 0450 stream() << " " << cppType(entry->paramType) << " i "; 0451 } 0452 stream() << ")" << Const(); 0453 0454 // function body inline only if not using dpointer 0455 // for BC mode 0456 if (!cfg().dpointer) { 0457 stream() << '\n'; 0458 startScope(); 0459 stream() << whitespace() << memberAccessorBody(entry, cfg().globalEnums); 0460 endScope(); 0461 stream() << '\n'; 0462 } else { 0463 stream() << ";\n\n"; 0464 } 0465 } 0466 0467 void KConfigHeaderGenerator::createImmutableGetters(const CfgEntry *entry) 0468 { 0469 stream() << whitespace() << "/**\n"; 0470 stream() << whitespace() << " Is " << entry->label << " Immutable\n"; 0471 stream() << whitespace() << "*/\n"; 0472 // Immutable 0473 if (cfg().staticAccessors) { 0474 stream() << whitespace() << "static\n"; 0475 } 0476 stream() << whitespace() << ""; 0477 stream() << "bool " << immutableFunction(entry->name) << "("; 0478 if (!entry->param.isEmpty()) { 0479 stream() << " " << cppType(entry->paramType) << " i "; 0480 } 0481 stream() << ")" << Const(); 0482 // function body inline only if not using dpointer 0483 // for BC mode 0484 if (!cfg().dpointer) { 0485 stream() << '\n'; 0486 startScope(); 0487 memberImmutableBody(entry, cfg().globalEnums); 0488 endScope(); 0489 stream() << '\n'; 0490 } else { 0491 stream() << ";\n\n"; 0492 } 0493 } 0494 0495 void KConfigHeaderGenerator::createItemAcessors(const CfgEntry *entry, const QString &returnType) 0496 { 0497 Q_UNUSED(returnType) 0498 0499 // Item accessor 0500 if (!cfg().itemAccessors) { 0501 return; 0502 } 0503 0504 const QString declType = entry->signalList.isEmpty() ? QStringLiteral("Item") + itemType(entry->type) : QStringLiteral("KConfigCompilerSignallingItem"); 0505 0506 stream() << whitespace() << "/**\n"; 0507 stream() << whitespace() << " Get Item object corresponding to " << entry->name << "()" << '\n'; 0508 stream() << whitespace() << "*/\n"; 0509 stream() << whitespace() << declType << " *" << getFunction(entry->name) << "Item("; 0510 if (!entry->param.isEmpty()) { 0511 stream() << " " << cppType(entry->paramType) << " i "; 0512 } 0513 stream() << ")"; 0514 if (!cfg().dpointer) { 0515 stream() << '\n'; 0516 startScope(); 0517 stream() << whitespace() << itemAccessorBody(entry, cfg()); 0518 endScope(); 0519 } else { 0520 stream() << ";\n"; 0521 } 0522 0523 stream() << '\n'; 0524 } 0525 0526 void KConfigHeaderGenerator::createDefaultValueMember(const CfgEntry *entry) 0527 { 0528 // Default value Accessor 0529 if (!((cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) && !entry->defaultValue.isEmpty())) { 0530 return; 0531 } 0532 stream() << whitespace() << "/**\n"; 0533 stream() << whitespace() << " Get " << entry->label << " default value\n"; 0534 stream() << whitespace() << "*/\n"; 0535 if (cfg().staticAccessors) { 0536 stream() << whitespace() << "static\n"; 0537 } 0538 stream() << whitespace() << ""; 0539 if (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) { 0540 stream() << enumType(entry, cfg().globalEnums); 0541 } else { 0542 stream() << cppType(entry->type); 0543 } 0544 stream() << " " << getDefaultFunction(entry->name) << "("; 0545 if (!entry->param.isEmpty()) { 0546 stream() << " " << cppType(entry->paramType) << " i "; 0547 } 0548 stream() << ")" << Const() << '\n'; 0549 stream() << whitespace() << "{\n"; 0550 stream() << whitespace() << " return "; 0551 if (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) { 0552 stream() << "static_cast<" << enumType(entry, cfg().globalEnums) << ">("; 0553 } 0554 stream() << getDefaultFunction(entry->name) << "_helper("; 0555 if (!entry->param.isEmpty()) { 0556 stream() << " i "; 0557 } 0558 stream() << ")"; 0559 if (cfg().useEnumTypes && entry->type == QLatin1String("Enum")) { 0560 stream() << ")"; 0561 } 0562 stream() << ";\n"; 0563 stream() << whitespace() << "}\n"; 0564 stream() << '\n'; 0565 } 0566 0567 void KConfigHeaderGenerator::createSingleton() 0568 { 0569 // Private constructor for singleton 0570 if (!cfg().singleton) { 0571 return; 0572 } 0573 0574 stream() << whitespace() << "" << cfg().className << "("; 0575 if (parseResult.cfgFileNameArg) { 0576 stream() << "KSharedConfig::Ptr config"; 0577 } 0578 if (cfg().parentInConstructor) { 0579 if (parseResult.cfgFileNameArg) { 0580 stream() << ", "; 0581 } 0582 stream() << "QObject *parent = nullptr"; 0583 } 0584 stream() << ");\n"; 0585 stream() << whitespace() << "friend class " << cfg().className << "Helper;\n\n"; 0586 } 0587 0588 void KConfigHeaderGenerator::createNonDPointerHelpers() 0589 { 0590 if (cfg().memberVariables == QLatin1String("dpointer")) { 0591 return; 0592 } 0593 0594 QString group; 0595 for (const auto *entry : std::as_const(parseResult.entries)) { 0596 if (entry->group != group) { 0597 group = entry->group; 0598 stream() << '\n'; 0599 stream() << whitespace() << "// " << group << '\n'; 0600 } 0601 stream() << whitespace() << "" << cppType(entry->type) << " " << varName(entry->name, cfg()); 0602 if (!entry->param.isEmpty()) { 0603 stream() << QStringLiteral("[%1]").arg(entry->paramMax + 1); 0604 } 0605 stream() << ";\n"; 0606 0607 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) { 0608 stream() << whitespace() << ""; 0609 if (cfg().staticAccessors) { 0610 stream() << "static "; 0611 } 0612 stream() << cppType(entry->type) << " " << getDefaultFunction(entry->name) << "_helper("; 0613 if (!entry->param.isEmpty()) { 0614 stream() << " " << cppType(entry->paramType) << " i "; 0615 } 0616 stream() << ")" << Const() << ";\n"; 0617 } 0618 } 0619 0620 stream() << "\n private:\n"; 0621 if (cfg().itemAccessors) { 0622 for (const auto *entry : std::as_const(parseResult.entries)) { 0623 const QString declType = 0624 entry->signalList.isEmpty() ? QStringLiteral("Item") + itemType(entry->type) : QStringLiteral("KConfigCompilerSignallingItem"); 0625 stream() << whitespace() << declType << " *" << itemVar(entry, cfg()); 0626 if (!entry->param.isEmpty()) { 0627 stream() << QStringLiteral("[%1]").arg(entry->paramMax + 1); 0628 } 0629 stream() << ";\n"; 0630 } 0631 } 0632 0633 if (parseResult.hasNonModifySignals) { 0634 stream() << whitespace() << "QSet<quint64> " << varName(QStringLiteral("settingsChanged"), cfg()) << ";\n"; 0635 } 0636 }