aboutsummaryrefslogtreecommitdiff
path: root/src/kconfig_compiler/KConfigHeaderGenerator.cpp
diff options
context:
space:
mode:
authorTomaz Canabrava <tcanabrava@kde.org>2020-01-17 10:03:43 +0000
committerTomaz Canabrava <tcanabrava@kde.org>2020-01-17 10:03:43 +0000
commit5f8c2ce63499d05dfb4753eb1acc21dccf21d434 (patch)
treefed718a3c8f4c4974411d612a79c4125ae3fffd8 /src/kconfig_compiler/KConfigHeaderGenerator.cpp
parent98c32e29f50465d4d4e16bafdf0491edbfb422b0 (diff)
downloadkconfig-5f8c2ce63499d05dfb4753eb1acc21dccf21d434.tar.gz
kconfig-5f8c2ce63499d05dfb4753eb1acc21dccf21d434.tar.bz2
Revert "WIP: Refactor KConfigXT"
This reverts commit 98c32e29f50465d4d4e16bafdf0491edbfb422b0. This broke kdevelop and kmymoney. I'm workin on the fixes and more unittests for them.
Diffstat (limited to 'src/kconfig_compiler/KConfigHeaderGenerator.cpp')
-rw-r--r--src/kconfig_compiler/KConfigHeaderGenerator.cpp612
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 &parameter : 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;
- }
-}