1 /*
2     This file is part of KDE.
3 
4     SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org>
5     SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
6     SPDX-FileCopyrightText: 2003 Zack Rusin <zack@kde.org>
7     SPDX-FileCopyrightText: 2006 Michaël Larouche <michael.larouche@kdemail.net>
8     SPDX-FileCopyrightText: 2008 Allen Winter <winter@kde.org>
9     SPDX-FileCopyrightText: 2020 Tomaz Cananbrava <tcanabrava@kde.org>
10 
11     SPDX-License-Identifier: LGPL-2.0-or-later
12 */
13 
14 #ifndef KCONFIGCODEGENERATORBASE_H
15 #define KCONFIGCODEGENERATORBASE_H
16 
17 #include <QFile>
18 #include <QString>
19 #include <QTextStream>
20 #include <QVector>
21 
22 #include "KConfigCommonStructs.h"
23 #include "KConfigParameters.h"
24 
25 class CfgEntry;
26 struct ParseResult;
27 
28 /* This class manages the base of writing a C - Based code */
29 class KConfigCodeGeneratorBase
30 {
31 public:
32     enum ScopeFinalizer {
33         None,
34         Semicolon,
35     };
36 
37     KConfigCodeGeneratorBase(const QString &inputFileName, // The kcfg file
38                              const QString &baseDir, // where we should store the generated file
39                              const QString &fileName, // the name of the generated file
40                              const KConfigParameters &parameters, // parameters passed to the generator
41                              ParseResult &parseResult // The pre processed configuration entries
42     );
43     virtual ~KConfigCodeGeneratorBase();
44 
45     // iterates over the header list adding an #include directive.
46     void addHeaders(const QStringList &header);
47 
48     // Create all the namespace indentation levels based on the parsed result and parameters */
49     void beginNamespaces();
50 
51     // Closes all the namespaces adding lines with single '}'
52     void endNamespaces();
53 
54     // Add the correct amount of whitespace in the code.
55     QString whitespace() const;
56 
57     // start a block scope `{` and increase indentation level.
58     void endScope(ScopeFinalizer finalizer = None);
59 
60     // end a block scope `}` and decrease indentation level.
61     void startScope();
62 
63     // start writing to the output file
64     virtual void start();
65 
66     // save the result on the disk
67     void save();
68 
69     // Code Implementations
70     // Implements the `Get` methods for the CfgEntry
71     // TODO: write to the stream directly without returning a QString.
72     QString memberAccessorBody(const CfgEntry *e, bool globalEnums) const;
73 
74     // Implements the is<Param>Immutable for the CfgEntry
75     void memberImmutableBody(const CfgEntry *e, bool globalEnums);
76 
77     // Implements the `Set` methods for the CfgEntry
78     void memberMutatorBody(const CfgEntry *e);
79 
80     // This is the code that creates the logic for the Setter / Mutator.
81     // It *just* creates the if test, no body. The reason is that just
82     // the if test was more than 20 lines of code and hard to understand
83     // what was happening in a bigger function.
84     void createIfSetLogic(const CfgEntry *e, const QString &varExpression);
85 
86 protected:
87     /* advance the number of spaces for the indentation level */
88     void indent();
89 
90     /* reduce the number of spaces for the indentation level */
91     void unindent();
92 
inputFile()93     QString inputFile() const
94     {
95         return m_inputFile;
96     }
fileName()97     QString fileName() const
98     {
99         return m_fileName;
100     }
baseDir()101     QString baseDir() const
102     {
103         return m_baseDir;
104     }
This()105     QString This() const
106     {
107         return m_this;
108     }
Const()109     QString Const() const
110     {
111         return m_const;
112     }
cfg()113     KConfigParameters cfg() const
114     {
115         return m_cfg;
116     }
117 
118     // Can't be const.
stream()119     QTextStream &stream()
120     {
121         return m_stream;
122     }
123 
124     // HACK: This needs to be accessible because the HeaderGenerator actually modifies
125     // it while running. Considering that this is a the result of the xml Parse, and not
126     // the result of generating code, I consider this to be quite wrong - but moving the
127     // changes away from the header generator only created more problems and I have to
128     // investigate more.
129     ParseResult &parseResult; // the result of the parsed kcfg file
130 
131 private:
132     QString m_inputFile; // the base file name, input file is based on this.
133 
134     QString m_baseDir; // Where we are going to save the file
135     QString m_fileName; // The file name
136 
137     KConfigParameters m_cfg; // The parameters passed via the kcfgc file
138     QTextStream m_stream; // the stream that operates in the file to write data.
139     QFile m_file; // The file handler.
140 
141     // Special access to `this->` and `const` thru the code.
142     QString m_this;
143     QString m_const;
144     int m_indentLevel = 0;
145 };
146 
147 #endif
148