Changeset View
Changeset View
Standalone View
Standalone View
src/kconfig_compiler/KConfigCodeGeneratorBase.cpp
Show All 28 Lines | |||||
29 | 29 | | |||
30 | #include <QTextStream> | 30 | #include <QTextStream> | ||
31 | #include <QLatin1Char> | 31 | #include <QLatin1Char> | ||
32 | #include <QFileInfo> | 32 | #include <QFileInfo> | ||
33 | 33 | | |||
34 | #include <ostream> | 34 | #include <ostream> | ||
35 | #include <QDebug> | 35 | #include <QDebug> | ||
36 | 36 | | |||
37 | using std::endl; | 37 | #include <iostream> | ||
38 | | ||||
39 | namespace | | |||
40 | { | | |||
41 | QTextStream cout(stdout); | | |||
42 | QTextStream cerr(stderr); | | |||
43 | } | | |||
44 | 38 | | |||
45 | KConfigCodeGeneratorBase::KConfigCodeGeneratorBase( | 39 | KConfigCodeGeneratorBase::KConfigCodeGeneratorBase( | ||
46 | const QString &inputFile, | 40 | const QString &inputFile, | ||
47 | const QString &baseDir, | 41 | const QString &baseDir, | ||
48 | const QString &fileName, | 42 | const QString &fileName, | ||
49 | const KConfigParameters ¶meters, | 43 | const KConfigParameters ¶meters, | ||
50 | ParseResult &parseResult) | 44 | ParseResult &parseResult) | ||
51 | : m_inputFile(inputFile), m_baseDir(baseDir), m_fileName(fileName), m_cfg(parameters), parseResult(parseResult) | 45 | : m_inputFile(inputFile), m_baseDir(baseDir), m_fileName(fileName), m_cfg(parameters), parseResult(parseResult) | ||
52 | { | 46 | { | ||
53 | m_file.setFileName(m_fileName); | 47 | m_file.setFileName(m_fileName); | ||
54 | if (!m_file.open(QIODevice::WriteOnly)) { | 48 | if (!m_file.open(QIODevice::WriteOnly)) { | ||
55 | cerr << "Can not open '" << m_fileName << "for writing." << endl; | 49 | std::cerr << "Can not open '" << qPrintable(m_fileName) << "for writing." << std::endl; | ||
56 | exit(1); | 50 | exit(1); | ||
57 | } | 51 | } | ||
58 | m_stream.setDevice(&m_file); | 52 | m_stream.setDevice(&m_file); | ||
59 | m_stream.setCodec("utf-8"); | 53 | m_stream.setCodec("utf-8"); | ||
60 | 54 | | |||
61 | if (m_cfg.staticAccessors) { | 55 | if (m_cfg.staticAccessors) { | ||
62 | m_this = QStringLiteral("self()->"); | 56 | m_this = QStringLiteral("self()->"); | ||
63 | } else { | 57 | } else { | ||
Show All 37 Lines | 94 | for (int i = 0; i < m_indentLevel; i++) { | |||
101 | spaces.append(QLatin1Char(' ')); | 95 | spaces.append(QLatin1Char(' ')); | ||
102 | } | 96 | } | ||
103 | return spaces; | 97 | return spaces; | ||
104 | } | 98 | } | ||
105 | 99 | | |||
106 | void KConfigCodeGeneratorBase::startScope() | 100 | void KConfigCodeGeneratorBase::startScope() | ||
107 | { | 101 | { | ||
108 | m_stream << whitespace() << QLatin1Char('{'); | 102 | m_stream << whitespace() << QLatin1Char('{'); | ||
109 | m_stream << endl; | 103 | m_stream << '\n'; | ||
110 | indent(); | 104 | indent(); | ||
111 | } | 105 | } | ||
112 | 106 | | |||
113 | void KConfigCodeGeneratorBase::endScope(ScopeFinalizer finalizer) | 107 | void KConfigCodeGeneratorBase::endScope(ScopeFinalizer finalizer) | ||
114 | { | 108 | { | ||
115 | unindent(); | 109 | unindent(); | ||
116 | m_stream << whitespace() << QLatin1Char('}'); | 110 | m_stream << whitespace() << QLatin1Char('}'); | ||
117 | if (finalizer == ScopeFinalizer::Semicolon) { | 111 | if (finalizer == ScopeFinalizer::Semicolon) { | ||
118 | m_stream << ';'; | 112 | m_stream << ';'; | ||
119 | } | 113 | } | ||
120 | m_stream << endl; | 114 | m_stream << '\n'; | ||
121 | } | 115 | } | ||
122 | 116 | | |||
123 | void KConfigCodeGeneratorBase::start() | 117 | void KConfigCodeGeneratorBase::start() | ||
124 | { | 118 | { | ||
125 | const QString m_fileName = QFileInfo(m_inputFile).fileName(); | 119 | const QString m_fileName = QFileInfo(m_inputFile).fileName(); | ||
126 | m_stream << "// This file is generated by kconfig_compiler_kf5 from " << m_fileName << ".kcfg" << "." << endl; | 120 | m_stream << "// This file is generated by kconfig_compiler_kf5 from " << m_fileName << ".kcfg" << ".\n"; | ||
127 | m_stream << "// All changes you do to this file will be lost." << endl; | 121 | m_stream << "// All changes you do to this file will be lost.\n"; | ||
128 | } | 122 | } | ||
129 | 123 | | |||
130 | void KConfigCodeGeneratorBase::addHeaders(const QStringList &headerList) | 124 | void KConfigCodeGeneratorBase::addHeaders(const QStringList &headerList) | ||
131 | { | 125 | { | ||
132 | for (auto include : qAsConst(headerList)) { | 126 | for (auto include : qAsConst(headerList)) { | ||
133 | if (include.startsWith(QLatin1Char('"'))) { | 127 | if (include.startsWith(QLatin1Char('"'))) { | ||
134 | m_stream << "#include " << include << endl; | 128 | m_stream << "#include " << include << '\n'; | ||
135 | } else { | 129 | } else { | ||
136 | m_stream << "#include <" << include << ">" << endl; | 130 | m_stream << "#include <" << include << ">\n"; | ||
137 | } | 131 | } | ||
138 | } | 132 | } | ||
139 | } | 133 | } | ||
140 | 134 | | |||
141 | // adds as many 'namespace foo {' lines to p_out as | 135 | // adds as many 'namespace foo {' lines to p_out as | ||
142 | // there are namespaces in p_ns | 136 | // there are namespaces in p_ns | ||
143 | void KConfigCodeGeneratorBase::beginNamespaces() | 137 | void KConfigCodeGeneratorBase::beginNamespaces() | ||
144 | { | 138 | { | ||
145 | if (!m_cfg.nameSpace.isEmpty()) { | 139 | if (!m_cfg.nameSpace.isEmpty()) { | ||
146 | for (const QString &ns : m_cfg.nameSpace.split(QStringLiteral("::"))) { | 140 | for (const QString &ns : m_cfg.nameSpace.split(QStringLiteral("::"))) { | ||
147 | m_stream << "namespace " << ns << " {" << endl; | 141 | m_stream << "namespace " << ns << " {\n"; | ||
148 | } | 142 | } | ||
149 | m_stream << endl; | 143 | m_stream << '\n'; | ||
150 | } | 144 | } | ||
151 | } | 145 | } | ||
152 | 146 | | |||
153 | // adds as many '}' lines to p_out as | 147 | // adds as many '}' lines to p_out as | ||
154 | // there are namespaces in p_ns | 148 | // there are namespaces in p_ns | ||
155 | void KConfigCodeGeneratorBase::endNamespaces() | 149 | void KConfigCodeGeneratorBase::endNamespaces() | ||
156 | { | 150 | { | ||
157 | if (!m_cfg.nameSpace.isEmpty()) { | 151 | if (!m_cfg.nameSpace.isEmpty()) { | ||
158 | m_stream << endl; | 152 | m_stream << '\n'; | ||
159 | const int namespaceCount = m_cfg.nameSpace.count(QStringLiteral("::")) + 1; | 153 | const int namespaceCount = m_cfg.nameSpace.count(QStringLiteral("::")) + 1; | ||
160 | for (int i = 0; i < namespaceCount; ++i) { | 154 | for (int i = 0; i < namespaceCount; ++i) { | ||
161 | m_stream << "}" << endl; | 155 | m_stream << "}\n"; | ||
162 | } | 156 | } | ||
163 | } | 157 | } | ||
164 | } | 158 | } | ||
165 | 159 | | |||
166 | // returns the member accesor implementation | 160 | // returns the member accesor implementation | ||
167 | // which should go in the h file if inline | 161 | // which should go in the h file if inline | ||
168 | // or the cpp file if not inline | 162 | // or the cpp file if not inline | ||
169 | QString KConfigCodeGeneratorBase::memberAccessorBody(const CfgEntry *e, bool globalEnums) const | 163 | QString KConfigCodeGeneratorBase::memberAccessorBody(const CfgEntry *e, bool globalEnums) const | ||
Show All 10 Lines | 164 | { | |||
180 | } | 174 | } | ||
181 | out << m_this << varPath(n, m_cfg); | 175 | out << m_this << varPath(n, m_cfg); | ||
182 | if (!e->param.isEmpty()) { | 176 | if (!e->param.isEmpty()) { | ||
183 | out << "[i]"; | 177 | out << "[i]"; | ||
184 | } | 178 | } | ||
185 | if (useEnumType) { | 179 | if (useEnumType) { | ||
186 | out << ")"; | 180 | out << ")"; | ||
187 | } | 181 | } | ||
188 | out << ";" << endl; | 182 | out << ";\n"; | ||
189 | 183 | | |||
190 | return result; | 184 | return result; | ||
191 | } | 185 | } | ||
192 | 186 | | |||
193 | void KConfigCodeGeneratorBase::createIfSetLogic(const CfgEntry *e, const QString &varExpression) | 187 | void KConfigCodeGeneratorBase::createIfSetLogic(const CfgEntry *e, const QString &varExpression) | ||
194 | { | 188 | { | ||
195 | const QString n = e->name; | 189 | const QString n = e->name; | ||
196 | const QString t = e->type; | 190 | const QString t = e->type; | ||
Show All 31 Lines | |||||
228 | void KConfigCodeGeneratorBase::memberMutatorBody(const CfgEntry *e) | 222 | void KConfigCodeGeneratorBase::memberMutatorBody(const CfgEntry *e) | ||
229 | { | 223 | { | ||
230 | QString n = e->name; | 224 | QString n = e->name; | ||
231 | QString t = e->type; | 225 | QString t = e->type; | ||
232 | 226 | | |||
233 | // HACK: Don't open '{' manually, use startScope / endScope to automatically handle whitespace indentation. | 227 | // HACK: Don't open '{' manually, use startScope / endScope to automatically handle whitespace indentation. | ||
234 | if (!e->min.isEmpty()) { | 228 | if (!e->min.isEmpty()) { | ||
235 | if (e->min != QLatin1String("0") || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) | 229 | if (e->min != QLatin1String("0") || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) | ||
236 | m_stream << whitespace() << "if (v < " << e->min << ")" << endl; | 230 | m_stream << whitespace() << "if (v < " << e->min << ")\n"; | ||
237 | m_stream << whitespace() << "{" << endl; | 231 | m_stream << whitespace() << "{\n"; | ||
238 | m_stream << whitespace(); addDebugMethod(m_stream, m_cfg, n); | 232 | m_stream << whitespace(); addDebugMethod(m_stream, m_cfg, n); | ||
239 | m_stream << ": value \" << v << \" is less than the minimum value of " << e->min << "\";" << endl; | 233 | m_stream << ": value \" << v << \" is less than the minimum value of " << e->min << "\";\n"; | ||
240 | m_stream << whitespace() << " v = " << e->min << ";" << endl; | 234 | m_stream << whitespace() << " v = " << e->min << ";\n"; | ||
241 | m_stream << whitespace() << "}" << endl; | 235 | m_stream << whitespace() << "}\n"; | ||
242 | } | 236 | } | ||
243 | } | 237 | } | ||
244 | 238 | | |||
245 | if (!e->max.isEmpty()) { | 239 | if (!e->max.isEmpty()) { | ||
246 | m_stream << endl; | 240 | m_stream << '\n'; | ||
247 | m_stream << whitespace() << "if (v > " << e->max << ")" << endl; | 241 | m_stream << whitespace() << "if (v > " << e->max << ")\n"; | ||
248 | m_stream << whitespace() << "{" << endl; | 242 | m_stream << whitespace() << "{\n"; | ||
249 | m_stream << whitespace(); addDebugMethod(m_stream, m_cfg, n); | 243 | m_stream << whitespace(); addDebugMethod(m_stream, m_cfg, n); | ||
250 | m_stream << ": value \" << v << \" is greater than the maximum value of " << e->max << "\";" << endl; | 244 | m_stream << ": value \" << v << \" is greater than the maximum value of " << e->max << "\";\n"; | ||
251 | m_stream << whitespace() << " v = " << e->max << ";" << endl; | 245 | m_stream << whitespace() << " v = " << e->max << ";\n"; | ||
252 | m_stream << whitespace() << "}" << endl << endl; | 246 | m_stream << whitespace() << "}\n\n"; | ||
253 | } | 247 | } | ||
254 | 248 | | |||
255 | const QString varExpression = m_this + varPath(n, m_cfg) + (e->param.isEmpty() ? QString() : QStringLiteral("[i]")); | 249 | const QString varExpression = m_this + varPath(n, m_cfg) + (e->param.isEmpty() ? QString() : QStringLiteral("[i]")); | ||
256 | 250 | | |||
257 | // TODO: Remove this `hasBody` logic, always use an '{' for the if. | 251 | // TODO: Remove this `hasBody` logic, always use an '{' for the if. | ||
258 | const bool hasBody = !e->signalList.empty() || m_cfg.generateProperties; | 252 | const bool hasBody = !e->signalList.empty() || m_cfg.generateProperties; | ||
259 | 253 | | |||
260 | // m_this call creates an `if (someTest ...) that's just to long to throw over the code. | 254 | // m_this call creates an `if (someTest ...) that's just to long to throw over the code. | ||
261 | createIfSetLogic(e, varExpression); | 255 | createIfSetLogic(e, varExpression); | ||
262 | m_stream << (hasBody ? " {" : "") << endl; | 256 | m_stream << (hasBody ? " {" : "") << '\n'; | ||
263 | m_stream << whitespace() << " " << varExpression << " = v;" << endl; | 257 | m_stream << whitespace() << " " << varExpression << " = v;\n"; | ||
264 | 258 | | |||
265 | const auto listSignal = e->signalList; | 259 | const auto listSignal = e->signalList; | ||
266 | for (const Signal &signal : qAsConst(listSignal)) { | 260 | for (const Signal &signal : qAsConst(listSignal)) { | ||
267 | if (signal.modify) { | 261 | if (signal.modify) { | ||
268 | m_stream << whitespace() << " Q_EMIT " << m_this << signal.name << "();" << endl; | 262 | m_stream << whitespace() << " Q_EMIT " << m_this << signal.name << "();\n"; | ||
269 | } else { | 263 | } else { | ||
270 | m_stream << whitespace() << " " << m_this << varPath(QStringLiteral("settingsChanged"), m_cfg) | 264 | m_stream << whitespace() << " " << m_this << varPath(QStringLiteral("settingsChanged"), m_cfg) | ||
271 | << " |= " << signalEnumName(signal.name) << ";" << endl; | 265 | << " |= " << signalEnumName(signal.name) << ";\n"; | ||
272 | } | 266 | } | ||
273 | } | 267 | } | ||
274 | if (hasBody) { | 268 | if (hasBody) { | ||
275 | m_stream << whitespace() << "}" << endl; | 269 | m_stream << whitespace() << "}\n"; | ||
276 | } | 270 | } | ||
277 | } | 271 | } |