diff options
Diffstat (limited to 'src/kconfig_compiler/KConfigHeaderGenerator.cpp')
-rw-r--r-- | src/kconfig_compiler/KConfigHeaderGenerator.cpp | 612 |
1 files changed, 0 insertions, 612 deletions
diff --git a/src/kconfig_compiler/KConfigHeaderGenerator.cpp b/src/kconfig_compiler/KConfigHeaderGenerator.cpp deleted file mode 100644 index 088f64e7..00000000 --- a/src/kconfig_compiler/KConfigHeaderGenerator.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2020 Tomaz Cananbrava (tcanabrava@kde.org) - Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> - Copyright (c) 2003 Waldo Bastian <bastian@kde.org> - Copyright (c) 2003 Zack Rusin <zack@kde.org> - Copyright (c) 2006 MichaĆ«l Larouche <michael.larouche@kdemail.net> - Copyright (c) 2008 Allen Winter <winter@kde.org> - Copyright (C) 2020 Tomaz Cananbrava (tcanabrava@kde.org) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "KConfigHeaderGenerator.h" -#include "KConfigCommonStructs.h" - -#include <QTextStream> -#include <QDebug> - -namespace -{ -QTextStream cout(stdout); -QTextStream cerr(stderr); -} - -KConfigHeaderGenerator::KConfigHeaderGenerator( - const QString& inputFile, - const QString& baseDir, - const KConfigXTParameters &cfg, - ParseResult &parseResult) - : KConfigCodeGeneratorBase(inputFile, baseDir, baseDir + cfg.baseName + QLatin1Char('.') + cfg.headerExtension, cfg, parseResult) -{ -} - -void KConfigHeaderGenerator::start() -{ - KConfigCodeGeneratorBase::start(); - startHeaderGuards(); - createHeaders(); - - beginNamespaces(); - - createForwardDeclarations(); - - doClassDefinition(); - - endNamespaces(); - endHeaderGuards(); -} - -void KConfigHeaderGenerator::doClassDefinition() -{ - stream << "class " << cfg.visibility << cfg.className << " : public " << cfg.inherits << endl; - startScope(); - - // Add Q_OBJECT macro if the config need signals. - if (!parseResult.signalList.isEmpty() || cfg.generateProperties) { - stream << " Q_OBJECT" << endl; - } - stream << " public:" << endl; - implementEnums(); - createConstructor(); - createDestructor(); - - for (auto *entry : qAsConst(parseResult.entries)) { - const QString n = entry->name; - const QString t = entry->type; - - const QString returnType = (cfg.useEnumTypes && t == QLatin1String("Enum")) - ? enumType(entry, cfg.globalEnums) - : cppType(t); - - createSetters(entry); - createProperties(entry, returnType); - createGetters(entry, returnType); - createDefaultValueMember(entry); - createItemAcessors(entry, returnType); - } - - createSignals(); - stream << " protected:" << endl; - createSingleton(); - - // TODO: Move those to functions too. - if (parseResult.hasNonModifySignals) { - stream << whitespace() << "bool usrSave() override;" << endl; - } - - // Member variables - if (!cfg.memberVariables.isEmpty() && cfg.memberVariables != QLatin1String("private") && cfg.memberVariables != QLatin1String("dpointer")) { - stream << " " << cfg.memberVariables << ":" << endl; - } - - // Class Parameters - for (const auto ¶meter : qAsConst(parseResult.parameters)) { - stream << whitespace() << "" << cppType(parameter.type) << " mParam" << parameter.name << ";" << endl; - } - - createNonDPointerHelpers(); - createDPointer(); - - if (cfg.customAddons) { - stream << whitespace() << "// Include custom additions" << endl; - stream << whitespace() << "#include \"" << cfg.baseName << "_addons." << cfg.headerExtension << '"' << endl; - } - - endScope(ScopeFinalizer::Semicolon); -} - -void KConfigHeaderGenerator::createHeaders() -{ - addHeaders(cfg.headerIncludes); - if (cfg.headerIncludes.size()) { - stream << endl; - } - - if (!cfg.singleton && parseResult.parameters.isEmpty()) { - addHeaders({QStringLiteral("qglobal.h")}); - } - - if (cfg.inherits == QLatin1String("KCoreConfigSkeleton")) { - addHeaders({QStringLiteral("kcoreconfigskeleton.h")}); - } else { - addHeaders({QStringLiteral("kconfigskeleton.h")}); - } - - addHeaders({QStringLiteral("QCoreApplication"), QStringLiteral("QDebug")}); - stream << endl; - - addHeaders(parseResult.includes); - if (parseResult.includes.size()) { - stream << endl; - } -} - -void KConfigHeaderGenerator::startHeaderGuards() -{ - const bool hasNamespace = !cfg.nameSpace.isEmpty(); - const QString namespaceName = QString(QString(cfg.nameSpace).replace(QLatin1String("::"), QLatin1String("_"))).toUpper(); - const QString namespaceStr = hasNamespace ? namespaceName + QLatin1Char('_') : QStringLiteral(""); - const QString defineName = namespaceStr + cfg.className.toUpper() + QStringLiteral("_H"); - - stream << "#ifndef " << defineName << endl; - stream << "#define " << defineName << endl; - stream << endl; -} - -void KConfigHeaderGenerator::endHeaderGuards() -{ - stream << endl; - stream << "#endif"; - stream << endl; - // HACK: Original files ended with two last newlines, add them. - stream << endl; -} - -void KConfigHeaderGenerator::implementChoiceEnums(const CfgEntry *entry, const CfgEntry::Choices &choices) -{ - const QList<CfgEntry::Choice> chlist = choices.choices; - - if (chlist.isEmpty()) { - return; - } - - QStringList values; - for (const auto choice : qAsConst(chlist)) { - values.append(choices.prefix + choice.name); - } - - if (choices.name().isEmpty()) { - if (cfg.globalEnums) { - stream << whitespace() << "enum " << enumName(entry->name, entry->choices) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; - } else { - // Create an automatically named enum - stream << whitespace() << "class " << enumName(entry->name, entry->choices) << endl; - stream << whitespace() << "{" << endl; - stream << whitespace() << " public:" << endl; - stream << whitespace() << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };" << endl; - stream << whitespace() << "};" << endl; - } - } else if (!choices.external()) { - // Create a named enum - stream << whitespace() << "enum " << enumName(entry->name, entry->choices) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; - } -} - -void KConfigHeaderGenerator::implementValueEnums(const CfgEntry *entry, const QStringList &values) -{ - if (values.isEmpty()) { - return; - } - - if (cfg.globalEnums) { - // ### FIXME!! - // make the following string table an index-based string search! - // ### - stream << whitespace() << "enum " << enumName(entry->param) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; - stream << whitespace() << "static const char* const " << enumName(entry->param) << "ToString[];" << endl; - } else { - stream << whitespace() << "class " << enumName(entry->param) << endl; - stream << whitespace() << "{" << endl; - stream << whitespace() << " public:" << endl; - stream << whitespace() << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };" << endl; - stream << whitespace() << " static const char* const enumToString[];" << endl; - stream << whitespace() << "};" << endl; - } -} - -void KConfigHeaderGenerator::implementEnums() -{ - if (!parseResult.entries.size()) { - return; - } - - for (const auto entry : qAsConst(parseResult.entries)) { - const CfgEntry::Choices &choices = entry->choices; - const QStringList values = entry->paramValues; - - implementChoiceEnums(entry, choices); - implementValueEnums(entry, values); - } - stream << endl; -} - -void KConfigHeaderGenerator::createSignals() -{ - // Signal definition. - const bool hasSignals = !parseResult.signalList.isEmpty(); - - unsigned val = 1 << parseResult.signalList.size(); - if (!val) { - cerr << "Too many signals to create unique bit masks" << endl; - exit(1); - } - - if (!hasSignals) { - return; - } - - stream << "\n enum {" << endl; - val = 1; - - // HACK: Use C-Style for add a comma in all but the last element, - // just to make the source generated code equal to the old one. - // When we are sure, revert this to a range-based-for and just add - // a last comma, as it's valid c++. - for (int i = 0, end = parseResult.signalList.size(); i < end; i++) { - auto signal = parseResult.signalList.at(i); - stream << whitespace() << " " << signalEnumName(signal.name) << " = 0x" << hex << val; - if (i != end-1) { - stream << "," << endl; - } - - val <<= 1; - } - stream << endl; - stream << whitespace() << "};" << dec << endl << endl; - - stream << " Q_SIGNALS:"; - for (const Signal &signal : qAsConst(parseResult.signalList)) { - stream << endl; - if (!signal.label.isEmpty()) { - stream << whitespace() << "/**" << endl; - stream << whitespace() << " " << signal.label << endl; - stream << whitespace() << "*/" << endl; - } - stream << whitespace() << "void " << signal.name << "("; - QList<Param>::ConstIterator it, itEnd = signal.arguments.constEnd(); - for (it = signal.arguments.constBegin(); it != itEnd;) { - Param argument = *it; - QString type = param(argument.type); - if (cfg.useEnumTypes && argument.type == QLatin1String("Enum")) { - for (auto *entry : qAsConst(parseResult.entries)) { - if (entry->name == argument.name) { - type = enumType(entry, cfg.globalEnums); - break; - } - } - } - stream << type << " " << argument.name; - if (++it != itEnd) { - stream << ", "; - } - } - stream << ");" << endl; - } - stream << endl; - - stream << " private:" << endl; - stream << whitespace() << "void itemChanged(quint64 flags);" << endl; - stream << endl; -} - -void KConfigHeaderGenerator::createDPointer() -{ - if (!cfg.dpointer) { - return; - } - - // use a private class for both member variables and items - stream << " private:" << endl; - for (const auto &entry : qAsConst(parseResult.entries)) { - if (cfg.allDefaultGetters || cfg.defaultGetters.contains(entry->name)) { - stream << whitespace() << ""; - if (cfg.staticAccessors) { - stream << "static "; - } - stream << cppType(entry->type) << " " << getDefaultFunction(entry->name) << "_helper("; - if (!entry->param.isEmpty()) { - stream << " " << cppType(entry->paramType) << " i "; - } - stream << ")" << Const << ";" << endl; - } - } - stream << whitespace() << "" << cfg.className << "Private *d;" << endl; -} - -void KConfigHeaderGenerator::createConstructor() -{ - if (cfg.singleton) { - stream << whitespace() << "static " << cfg.className << " *self();" << endl; - if (parseResult.cfgFileNameArg) { - stream << whitespace() << "static void instance(const QString& cfgfilename);" << endl; - stream << whitespace() << "static void instance(KSharedConfig::Ptr config);" << endl; - } - return; - } - - stream << whitespace() << "" << cfg.className << "("; - if (parseResult.cfgFileNameArg) { - if (cfg.forceStringFilename) - stream << " const QString &cfgfilename" << (parseResult.parameters.isEmpty() ? " = QString()" : ", "); - else - stream << " KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", "); - } - - bool first = true; - for (const auto parameter : qAsConst(parseResult.parameters)) { - if (first) { - first = false; - } else { - stream << ","; - } - - stream << " " << param(parameter.type) << " " << parameter.name; - } - - if (cfg.parentInConstructor) { - if (parseResult.cfgFileNameArg || !parseResult.parameters.isEmpty()) { - stream << ","; - } - stream << " QObject *parent = nullptr"; - } - stream << " );" << endl; -} - -void KConfigHeaderGenerator::createDestructor() -{ - stream << whitespace() << "~" << cfg.className << "();" << endl << endl; -} - -void KConfigHeaderGenerator::createForwardDeclarations() -{ - // Private class declaration - if (cfg.dpointer) { - stream << "class " << cfg.className << "Private;" << endl << endl; - } -} - -void KConfigHeaderGenerator::createProperties(const CfgEntry *entry, const QString& returnType) -{ - if (!cfg.generateProperties) { - return; - } - stream << whitespace() << "Q_PROPERTY(" << returnType << ' ' << getFunction(entry->name); - stream << " READ " << getFunction(entry->name); - - if (cfg.allMutators || cfg.mutators.contains(entry->name)) { - const QString signal = changeSignalName(entry->name); - stream << " WRITE " << setFunction(entry->name); - stream << " NOTIFY " << signal; - - //If we have the modified signal, we'll also need - //the changed signal as well - Signal s; - s.name = signal; - s.modify = true; - parseResult.signalList.append(s); - } else { - stream << " CONSTANT"; - } - stream << ")" << endl; -} - -void KConfigHeaderGenerator::createSetters(const CfgEntry *entry) -{ - // Manipulator - if (!cfg.allMutators && !cfg.mutators.contains(entry->name)) { - return; - } - - stream << whitespace() << "/**" << endl; - stream << whitespace() << " Set " << entry->label << endl; - stream << whitespace() << "*/" << endl; - - if (cfg.staticAccessors) { - stream << whitespace() << "static" << endl; - } - - stream << whitespace() << "void " << setFunction(entry->name) << "( "; - if (!entry->param.isEmpty()) { - stream <<cppType(entry->paramType) << " i, "; - } - - stream << (cfg.useEnumTypes && entry->type == QLatin1String("Enum") - ? enumType(entry, cfg.globalEnums) - : param(entry->type)); - - stream << " v )"; - - // function body inline only if not using dpointer - // for BC mode - if (!cfg.dpointer) { - stream << endl; - startScope(); - memberMutatorBody(entry); - endScope(); - stream << endl; - } else { - stream << ";" << endl << endl; - } -} - -void KConfigHeaderGenerator::createGetters(const CfgEntry *entry, const QString& returnType) -{ - // Accessor - stream << whitespace() << "/**" << endl; - stream << whitespace() << " Get " << entry->label << endl; - stream << whitespace() << "*/" << endl; - if (cfg.staticAccessors) { - stream << whitespace() << "static" << endl; - } - stream << whitespace() << ""; - stream << returnType; - stream << " " << getFunction(entry->name) << "("; - if (!entry->param.isEmpty()) { - stream << " " << cppType(entry->paramType) << " i "; - } - stream << ")" << Const; - - // function body inline only if not using dpointer - // for BC mode - if (!cfg.dpointer) { - stream << endl; - startScope(); - stream << whitespace() << memberAccessorBody(entry, cfg.globalEnums); - endScope(); - stream << endl; - } else { - stream << ";" << endl << endl; - } -} - -void KConfigHeaderGenerator::createItemAcessors(const CfgEntry *entry, const QString& returnType) -{ - // Item accessor - if (!cfg.itemAccessors) { - return; - } - stream << whitespace() << "/**" << endl; - stream << whitespace() << " Get Item object corresponding to " << entry->name << "()" - << endl; - stream << whitespace() << "*/" << endl; - stream << whitespace() << "Item" << itemType(entry->type) << " *" - << getFunction(entry->name) << "Item("; - if (!entry->param.isEmpty()) { - stream << " " << cppType(entry->paramType) << " i "; - } - stream << ")"; - if (!cfg.dpointer) { - stream << endl; - startScope(); - stream << whitespace() << itemAccessorBody(entry, cfg); - endScope(); - } else { - stream << ";" << endl; - } - - stream <<endl; -} - -void KConfigHeaderGenerator::createDefaultValueMember(const CfgEntry *entry) -{ - // Default value Accessor - if (! ((cfg.allDefaultGetters || cfg.defaultGetters.contains(entry->name)) && !entry->defaultValue.isEmpty())) { - return; - } - stream << whitespace() << "/**" << endl; - stream << whitespace() << " Get " << entry->label << " default value" << endl; - stream << whitespace() << "*/" << endl; - if (cfg.staticAccessors) { - stream << whitespace() << "static" << endl; - } - stream << whitespace() << ""; - if (cfg.useEnumTypes && entry->type == QLatin1String("Enum")) { - stream << enumType(entry, cfg.globalEnums); - } else { - stream << cppType(entry->type); - } - stream << " " << getDefaultFunction(entry->name) << "("; - if (!entry->param.isEmpty()) { - stream << " " << cppType(entry->paramType) << " i "; - } - stream << ")" << Const << endl; - stream << whitespace() << "{" << endl; - stream << whitespace() << " return "; - if (cfg.useEnumTypes && entry->type == QLatin1String("Enum")) { - stream << "static_cast<" << enumType(entry, cfg.globalEnums) << ">("; - } - stream << getDefaultFunction(entry->name) << "_helper("; - if (!entry->param.isEmpty()) { - stream << " i "; - } - stream << ")"; - if (cfg.useEnumTypes && entry->type == QLatin1String("Enum")) { - stream << ")"; - } - stream << ";" << endl; - stream << whitespace() << "}" << endl; - stream << endl; -} - -void KConfigHeaderGenerator::createSingleton() -{ - // Private constructor for singleton - if (!cfg.singleton) { - return; - } - - stream << whitespace() << "" << cfg.className << "("; - if (parseResult.cfgFileNameArg) { - stream << "KSharedConfig::Ptr config"; - } - if (cfg.parentInConstructor) { - if (parseResult.cfgFileNameArg) { - stream << ", "; - } - stream << "QObject *parent = nullptr"; - } - stream << ");" << endl; - stream << whitespace() << "friend class " << cfg.className << "Helper;" << endl << endl; -} - -void KConfigHeaderGenerator::createNonDPointerHelpers() -{ - if (cfg.memberVariables == QLatin1String("dpointer")) { - return; - } - - QString group; - for (auto *entry : qAsConst(parseResult.entries)) { - if (entry->group != group) { - group = entry->group; - stream << endl; - stream << whitespace() << "// " << group << endl; - } - stream << whitespace() << "" << cppType(entry->type) << " " << varName(entry->name, cfg); - if (!entry->param.isEmpty()) { - stream << QStringLiteral("[%1]").arg(entry->paramMax + 1); - } - stream << ";" << endl; - - if (cfg.allDefaultGetters || cfg.defaultGetters.contains(entry->name)) { - stream << whitespace() << ""; - if (cfg.staticAccessors) { - stream << "static "; - } - stream << cppType(entry->type) << " " << getDefaultFunction(entry->name) << "_helper("; - if (!entry->param.isEmpty()) { - stream << " " << cppType(entry->paramType) << " i "; - } - stream << ")" << Const << ";" << endl; - } - } - - stream << endl << " private:" << endl; - if (cfg.itemAccessors) { - for (auto *entry : qAsConst(parseResult.entries)) { - stream << whitespace() << "Item" << itemType(entry->type) << " *" << itemVar(entry, cfg); - if (!entry->param.isEmpty()) { - stream << QStringLiteral("[%1]").arg(entry->paramMax + 1); - } - stream << ";" << endl; - } - } - - if (parseResult.hasNonModifySignals) { - stream << whitespace() << "uint " << varName(QStringLiteral("settingsChanged"), cfg) << ";" << endl; - } -} |