Changeset View
Changeset View
Standalone View
Standalone View
src/kconfig_compiler/kconfig_compiler.cpp
Show All 37 Lines | |||||
38 | #include <qcommandlineparser.h> | 38 | #include <qcommandlineparser.h> | ||
39 | #include <qcommandlineoption.h> | 39 | #include <qcommandlineoption.h> | ||
40 | 40 | | |||
41 | #include <ostream> | 41 | #include <ostream> | ||
42 | #include <iostream> | 42 | #include <iostream> | ||
43 | #include <stdlib.h> | 43 | #include <stdlib.h> | ||
44 | 44 | | |||
45 | #include "../../kconfig_version.h" | 45 | #include "../../kconfig_version.h" | ||
46 | #include "KConfigXTParameters.h" | ||||
47 | #include "KConfigCommonStructs.h" | ||||
48 | #include "KConfigHeaderGenerator.h" | ||||
49 | #include "KConfigSourceGenerator.h" | ||||
46 | 50 | | |||
47 | namespace | 51 | namespace | ||
48 | { | 52 | { | ||
49 | QTextStream cout(stdout); | 53 | QTextStream cout(stdout); | ||
50 | QTextStream cerr(stderr); | 54 | QTextStream cerr(stderr); | ||
51 | } | 55 | } | ||
52 | 56 | | |||
53 | QStringList allNames; | 57 | QStringList allNames; | ||
54 | QRegExp *validNameRegexp; | 58 | QRegExp *validNameRegexp; | ||
55 | QString This; | 59 | QString This; | ||
56 | QString Const; | 60 | QString Const; | ||
57 | 61 | | |||
58 | /** | 62 | QString varName(const QString &n, const KConfigXTParameters &cfg) | ||
59 | Configuration Compiler Configuration | | |||
60 | */ | | |||
61 | class CfgConfig | | |||
62 | { | | |||
63 | public: | | |||
64 | CfgConfig(const QString &codegenFilename) | | |||
65 | { | | |||
66 | // Configure the compiler with some settings | | |||
67 | QSettings codegenConfig(codegenFilename, QSettings::IniFormat); | | |||
68 | | ||||
69 | nameSpace = codegenConfig.value(QStringLiteral("NameSpace")).toString(); | | |||
70 | className = codegenConfig.value(QStringLiteral("ClassName")).toString(); | | |||
71 | if (className.isEmpty()) { | | |||
72 | cerr << "Class name missing" << endl; | | |||
73 | exit(1); | | |||
74 | } | | |||
75 | inherits = codegenConfig.value(QStringLiteral("Inherits")).toString(); | | |||
76 | if (inherits.isEmpty()) { | | |||
77 | inherits = QStringLiteral("KConfigSkeleton"); | | |||
78 | } | | |||
79 | visibility = codegenConfig.value(QStringLiteral("Visibility")).toString(); | | |||
80 | if (!visibility.isEmpty()) { | | |||
81 | visibility += ' '; | | |||
82 | } | | |||
83 | parentInConstructor = codegenConfig.value(QStringLiteral("ParentInConstructor"), false).toBool(); | | |||
84 | forceStringFilename = codegenConfig.value(QStringLiteral("ForceStringFilename"), false).toBool(); | | |||
85 | singleton = codegenConfig.value(QStringLiteral("Singleton"), false).toBool(); | | |||
86 | staticAccessors = singleton; | | |||
87 | customAddons = codegenConfig.value(QStringLiteral("CustomAdditions"), false).toBool(); | | |||
88 | memberVariables = codegenConfig.value(QStringLiteral("MemberVariables")).toString(); | | |||
89 | dpointer = (memberVariables == QLatin1String("dpointer")); | | |||
90 | headerIncludes = codegenConfig.value(QStringLiteral("IncludeFiles"), QStringList()).toStringList(); | | |||
91 | sourceIncludes = codegenConfig.value(QStringLiteral("SourceIncludeFiles"), QStringList()).toStringList(); | | |||
92 | mutators = codegenConfig.value(QStringLiteral("Mutators"), QStringList()).toStringList(); | | |||
93 | allMutators = ((mutators.count() == 1) && (mutators.at(0).toLower() == QLatin1String("true"))); | | |||
94 | itemAccessors = codegenConfig.value(QStringLiteral("ItemAccessors"), false).toBool(); | | |||
95 | setUserTexts = codegenConfig.value(QStringLiteral("SetUserTexts"), false).toBool(); | | |||
96 | defaultGetters = codegenConfig.value(QStringLiteral("DefaultValueGetters"), QStringList()).toStringList(); | | |||
97 | allDefaultGetters = (defaultGetters.count() == 1) && (defaultGetters.at(0).toLower() == QLatin1String("true")); | | |||
98 | notifiers = codegenConfig.value(QStringLiteral("Notifiers"), QStringList()).toStringList(); | | |||
99 | allNotifiers = ((notifiers.count() == 1) && (notifiers.at(0).toLower() == QLatin1String("true"))); | | |||
100 | globalEnums = codegenConfig.value(QStringLiteral("GlobalEnums"), false).toBool(); | | |||
101 | useEnumTypes = codegenConfig.value(QStringLiteral("UseEnumTypes"), false).toBool(); | | |||
102 | const QString trString = codegenConfig.value(QStringLiteral("TranslationSystem")).toString().toLower(); | | |||
103 | generateProperties = codegenConfig.value(QStringLiteral("GenerateProperties"), false).toBool(); | | |||
104 | if (trString == QLatin1String("kde")) { | | |||
105 | translationSystem = KdeTranslation; | | |||
106 | translationDomain = codegenConfig.value(QStringLiteral("TranslationDomain")).toString(); | | |||
107 | } else { | | |||
108 | if (!trString.isEmpty() && trString != QLatin1String("qt")) { | | |||
109 | cerr << "Unknown translation system, falling back to Qt tr()" << endl; | | |||
110 | } | | |||
111 | translationSystem = QtTranslation; | | |||
112 | } | | |||
113 | qCategoryLoggingName = codegenConfig.value(QStringLiteral("CategoryLoggingName"), QString()).toString(); | | |||
114 | headerExtension = codegenConfig.value(QStringLiteral("HeaderExtension"), QStringLiteral("h")).toString(); | | |||
115 | sourceExtension = codegenConfig.value(QStringLiteral("SourceExtension"), QStringLiteral("cpp")).toString(); | | |||
116 | } | | |||
117 | | ||||
118 | public: | | |||
119 | enum TranslationSystem { | | |||
120 | QtTranslation, | | |||
121 | KdeTranslation | | |||
122 | }; | | |||
123 | | ||||
124 | // These are read from the .kcfgc configuration file | | |||
125 | QString nameSpace; // The namespace for the class to be generated | | |||
126 | QString className; // The class name to be generated | | |||
127 | QString inherits; // The class the generated class inherits (if empty, from KConfigSkeleton) | | |||
128 | QString visibility; | | |||
129 | bool parentInConstructor; // The class has the optional parent parameter in its constructor | | |||
130 | bool forceStringFilename; | | |||
131 | bool singleton; // The class will be a singleton | | |||
132 | bool staticAccessors; // provide or not static accessors | | |||
133 | bool customAddons; | | |||
134 | QString memberVariables; | | |||
135 | QStringList headerIncludes; | | |||
136 | QStringList sourceIncludes; | | |||
137 | QStringList mutators; | | |||
138 | QStringList defaultGetters; | | |||
139 | QStringList notifiers; | | |||
140 | QString qCategoryLoggingName; | | |||
141 | QString headerExtension; | | |||
142 | QString sourceExtension; | | |||
143 | bool allMutators; | | |||
144 | bool setUserTexts; | | |||
145 | bool allDefaultGetters; | | |||
146 | bool dpointer; | | |||
147 | bool globalEnums; | | |||
148 | bool useEnumTypes; | | |||
149 | bool itemAccessors; | | |||
150 | bool allNotifiers; | | |||
151 | TranslationSystem translationSystem; | | |||
152 | QString translationDomain; | | |||
153 | bool generateProperties; | | |||
154 | }; | | |||
155 | | ||||
156 | struct SignalArguments { | | |||
157 | QString type; | | |||
158 | QString variableName; | | |||
159 | }; | | |||
160 | | ||||
161 | class Signal | | |||
162 | { | | |||
163 | public: | | |||
164 | Signal() : modify(false) {} | | |||
165 | | ||||
166 | QString name; | | |||
167 | QString label; | | |||
168 | QList<SignalArguments> arguments; | | |||
169 | bool modify; | | |||
170 | }; | | |||
171 | | ||||
172 | class CfgEntry | | |||
173 | { | | |||
174 | public: | | |||
175 | struct Choice { | | |||
176 | QString name; | | |||
177 | QString context; | | |||
178 | QString label; | | |||
179 | QString toolTip; | | |||
180 | QString whatsThis; | | |||
181 | }; | | |||
182 | class Choices | | |||
183 | { | | |||
184 | public: | | |||
185 | Choices() {} | | |||
186 | Choices(const QList<Choice> &d, const QString &n, const QString &p) | | |||
187 | : prefix(p), choices(d), mName(n) | | |||
188 | { | | |||
189 | int i = n.indexOf(QLatin1String("::")); | | |||
190 | if (i >= 0) { | | |||
191 | mExternalQual = n.left(i + 2); | | |||
192 | } | | |||
193 | } | | |||
194 | QString prefix; | | |||
195 | QList<Choice> choices; | | |||
196 | const QString &name() const | | |||
197 | { | | |||
198 | return mName; | | |||
199 | } | | |||
200 | const QString &externalQualifier() const | | |||
201 | { | | |||
202 | return mExternalQual; | | |||
203 | } | | |||
204 | bool external() const | | |||
205 | { | | |||
206 | return !mExternalQual.isEmpty(); | | |||
207 | } | | |||
208 | private: | | |||
209 | QString mName; | | |||
210 | QString mExternalQual; | | |||
211 | }; | | |||
212 | | ||||
213 | CfgEntry(const QString &group, const QString &type, const QString &key, | | |||
214 | const QString &name, const QString &labelContext, const QString &label, | | |||
215 | const QString &toolTipContext, const QString &toolTip, const QString &whatsThisContext, const QString &whatsThis, const QString &code, | | |||
216 | const QString &defaultValue, const Choices &choices, const QList<Signal> &signalList, | | |||
217 | bool hidden) | | |||
218 | : mGroup(group), mType(type), mKey(key), mName(name), | | |||
219 | mLabelContext(labelContext), mLabel(label), mToolTipContext(toolTipContext), mToolTip(toolTip), | | |||
220 | mWhatsThisContext(whatsThisContext), mWhatsThis(whatsThis), | | |||
221 | mCode(code), mDefaultValue(defaultValue), mChoices(choices), | | |||
222 | mSignalList(signalList), mParamMax(0), mHidden(hidden) | | |||
223 | { | | |||
224 | } | | |||
225 | | ||||
226 | void setGroup(const QString &group) | | |||
227 | { | | |||
228 | mGroup = group; | | |||
229 | } | | |||
230 | QString group() const | | |||
231 | { | | |||
232 | return mGroup; | | |||
233 | } | | |||
234 | | ||||
235 | void setType(const QString &type) | | |||
236 | { | | |||
237 | mType = type; | | |||
238 | } | | |||
239 | QString type() const | | |||
240 | { | | |||
241 | return mType; | | |||
242 | } | | |||
243 | | ||||
244 | void setKey(const QString &key) | | |||
245 | { | | |||
246 | mKey = key; | | |||
247 | } | | |||
248 | QString key() const | | |||
249 | { | | |||
250 | return mKey; | | |||
251 | } | | |||
252 | | ||||
253 | void setName(const QString &name) | | |||
254 | { | | |||
255 | mName = name; | | |||
256 | } | | |||
257 | QString name() const | | |||
258 | { | | |||
259 | return mName; | | |||
260 | } | | |||
261 | | ||||
262 | void setLabelContext(const QString &labelContext) | | |||
263 | { | | |||
264 | mLabelContext = labelContext; | | |||
265 | } | | |||
266 | QString labelContext() const | | |||
267 | { | | |||
268 | return mLabelContext; | | |||
269 | } | | |||
270 | | ||||
271 | void setLabel(const QString &label) | | |||
272 | { | | |||
273 | mLabel = label; | | |||
274 | } | | |||
275 | QString label() const | | |||
276 | { | | |||
277 | return mLabel; | | |||
278 | } | | |||
279 | | ||||
280 | void setToolTipContext(const QString &toolTipContext) | | |||
281 | { | | |||
282 | mToolTipContext = toolTipContext; | | |||
283 | } | | |||
284 | QString toolTipContext() const | | |||
285 | { | | |||
286 | return mToolTipContext; | | |||
287 | } | | |||
288 | | ||||
289 | void setToolTip(const QString &toolTip) | | |||
290 | { | | |||
291 | mToolTip = toolTip; | | |||
292 | } | | |||
293 | QString toolTip() const | | |||
294 | { | | |||
295 | return mToolTip; | | |||
296 | } | | |||
297 | | ||||
298 | void setWhatsThisContext(const QString &whatsThisContext) | | |||
299 | { | | |||
300 | mWhatsThisContext = whatsThisContext; | | |||
301 | } | | |||
302 | QString whatsThisContext() const | | |||
303 | { | | |||
304 | return mWhatsThisContext; | | |||
305 | } | | |||
306 | | ||||
307 | void setWhatsThis(const QString &whatsThis) | | |||
308 | { | | |||
309 | mWhatsThis = whatsThis; | | |||
310 | } | | |||
311 | QString whatsThis() const | | |||
312 | { | | |||
313 | return mWhatsThis; | | |||
314 | } | | |||
315 | | ||||
316 | void setDefaultValue(const QString &d) | | |||
317 | { | | |||
318 | mDefaultValue = d; | | |||
319 | } | | |||
320 | QString defaultValue() const | | |||
321 | { | | |||
322 | return mDefaultValue; | | |||
323 | } | | |||
324 | | ||||
325 | void setCode(const QString &d) | | |||
326 | { | | |||
327 | mCode = d; | | |||
328 | } | | |||
329 | QString code() const | | |||
330 | { | | |||
331 | return mCode; | | |||
332 | } | | |||
333 | | ||||
334 | void setMinValue(const QString &d) | | |||
335 | { | | |||
336 | mMin = d; | | |||
337 | } | | |||
338 | QString minValue() const | | |||
339 | { | | |||
340 | return mMin; | | |||
341 | } | | |||
342 | | ||||
343 | void setMaxValue(const QString &d) | | |||
344 | { | | |||
345 | mMax = d; | | |||
346 | } | | |||
347 | QString maxValue() const | | |||
348 | { | | |||
349 | return mMax; | | |||
350 | } | | |||
351 | | ||||
352 | void setParam(const QString &d) | | |||
353 | { | | |||
354 | mParam = d; | | |||
355 | } | | |||
356 | QString param() const | | |||
357 | { | | |||
358 | return mParam; | | |||
359 | } | | |||
360 | | ||||
361 | void setParamName(const QString &d) | | |||
362 | { | | |||
363 | mParamName = d; | | |||
364 | } | | |||
365 | QString paramName() const | | |||
366 | { | | |||
367 | return mParamName; | | |||
368 | } | | |||
369 | | ||||
370 | void setParamType(const QString &d) | | |||
371 | { | | |||
372 | mParamType = d; | | |||
373 | } | | |||
374 | QString paramType() const | | |||
375 | { | | |||
376 | return mParamType; | | |||
377 | } | | |||
378 | | ||||
379 | void setChoices(const QList<Choice> &d, const QString &n, const QString &p) | | |||
380 | { | | |||
381 | mChoices = Choices(d, n, p); | | |||
382 | } | | |||
383 | Choices choices() const | | |||
384 | { | | |||
385 | return mChoices; | | |||
386 | } | | |||
387 | | ||||
388 | void setParamValues(const QStringList &d) | | |||
389 | { | | |||
390 | mParamValues = d; | | |||
391 | } | | |||
392 | QStringList paramValues() const | | |||
393 | { | | |||
394 | return mParamValues; | | |||
395 | } | | |||
396 | | ||||
397 | void setParamDefaultValues(const QStringList &d) | | |||
398 | { | | |||
399 | mParamDefaultValues = d; | | |||
400 | } | | |||
401 | QString paramDefaultValue(int i) const | | |||
402 | { | | |||
403 | return mParamDefaultValues[i]; | | |||
404 | } | | |||
405 | | ||||
406 | void setParamMax(int d) | | |||
407 | { | | |||
408 | mParamMax = d; | | |||
409 | } | | |||
410 | int paramMax() const | | |||
411 | { | | |||
412 | return mParamMax; | | |||
413 | } | | |||
414 | | ||||
415 | void setSignalList(const QList<Signal> &value) | | |||
416 | { | | |||
417 | mSignalList = value; | | |||
418 | } | | |||
419 | QList<Signal> signalList() const | | |||
420 | { | | |||
421 | return mSignalList; | | |||
422 | } | | |||
423 | | ||||
424 | bool hidden() const | | |||
425 | { | | |||
426 | return mHidden; | | |||
427 | } | | |||
428 | | ||||
429 | void dump() const | | |||
430 | { | | |||
431 | cerr << "<entry>" << endl; | | |||
432 | cerr << " group: " << mGroup << endl; | | |||
433 | cerr << " type: " << mType << endl; | | |||
434 | cerr << " key: " << mKey << endl; | | |||
435 | cerr << " name: " << mName << endl; | | |||
436 | cerr << " label context: " << mLabelContext << endl; | | |||
437 | cerr << " label: " << mLabel << endl; | | |||
438 | // whatsthis | | |||
439 | cerr << " code: " << mCode << endl; | | |||
440 | // cerr << " values: " << mValues.join(":") << endl; | | |||
441 | | ||||
442 | if (!param().isEmpty()) { | | |||
443 | cerr << " param name: " << mParamName << endl; | | |||
444 | cerr << " param type: " << mParamType << endl; | | |||
445 | cerr << " paramvalues: " << mParamValues.join(QChar::fromLatin1(':')) << endl; | | |||
446 | } | | |||
447 | cerr << " default: " << mDefaultValue << endl; | | |||
448 | cerr << " hidden: " << mHidden << endl; | | |||
449 | cerr << " min: " << mMin << endl; | | |||
450 | cerr << " max: " << mMax << endl; | | |||
451 | cerr << "</entry>" << endl; | | |||
452 | } | | |||
453 | | ||||
454 | private: | | |||
455 | QString mGroup; | | |||
456 | QString mType; | | |||
457 | QString mKey; | | |||
458 | QString mName; | | |||
459 | QString mLabelContext; | | |||
460 | QString mLabel; | | |||
461 | QString mToolTipContext; | | |||
462 | QString mToolTip; | | |||
463 | QString mWhatsThisContext; | | |||
464 | QString mWhatsThis; | | |||
465 | QString mCode; | | |||
466 | QString mDefaultValue; | | |||
467 | QString mParam; | | |||
468 | QString mParamName; | | |||
469 | QString mParamType; | | |||
470 | Choices mChoices; | | |||
471 | QList<Signal> mSignalList; | | |||
472 | QStringList mParamValues; | | |||
473 | QStringList mParamDefaultValues; | | |||
474 | int mParamMax; | | |||
475 | bool mHidden; | | |||
476 | QString mMin; | | |||
477 | QString mMax; | | |||
478 | }; | | |||
479 | | ||||
480 | class Param | | |||
481 | { | | |||
482 | public: | | |||
483 | QString name; | | |||
484 | QString type; | | |||
485 | }; | | |||
486 | | ||||
487 | // returns the name of an member variable | | |||
488 | // use itemPath to know the full path | | |||
489 | // like using d-> in case of dpointer | | |||
490 | static QString varName(const QString &n, const CfgConfig &cfg) | | |||
491 | { | 63 | { | ||
492 | QString result; | 64 | QString result; | ||
493 | if (!cfg.dpointer) { | 65 | if (!cfg.dpointer) { | ||
494 | result = QChar::fromLatin1('m') + n; | 66 | result = QChar::fromLatin1('m') + n; | ||
495 | result[1] = result[1].toUpper(); | 67 | result[1] = result[1].toUpper(); | ||
496 | } else { | 68 | } else { | ||
497 | result = n; | 69 | result = n; | ||
498 | result[0] = result[0].toLower(); | 70 | result[0] = result[0].toLower(); | ||
499 | } | 71 | } | ||
500 | return result; | 72 | return result; | ||
501 | } | 73 | } | ||
502 | 74 | | |||
503 | static QString varPath(const QString &n, const CfgConfig &cfg) | 75 | QString varPath(const QString &n, const KConfigXTParameters &cfg) | ||
504 | { | 76 | { | ||
505 | QString result; | 77 | QString result; | ||
506 | if (cfg.dpointer) { | 78 | if (cfg.dpointer) { | ||
507 | result = "d->" + varName(n, cfg); | 79 | result = "d->" + varName(n, cfg); | ||
508 | } else { | 80 | } else { | ||
509 | result = varName(n, cfg); | 81 | result = varName(n, cfg); | ||
510 | } | 82 | } | ||
511 | return result; | 83 | return result; | ||
512 | } | 84 | } | ||
513 | 85 | | |||
514 | static QString enumName(const QString &n) | 86 | QString enumName(const QString &n) | ||
515 | { | 87 | { | ||
516 | QString result = QLatin1String("Enum") + n; | 88 | QString result = QLatin1String("Enum") + n; | ||
517 | result[4] = result[4].toUpper(); | 89 | result[4] = result[4].toUpper(); | ||
518 | return result; | 90 | return result; | ||
519 | } | 91 | } | ||
520 | 92 | | |||
521 | static QString enumName(const QString &n, const CfgEntry::Choices &c) | 93 | QString enumName(const QString &n, const CfgEntry::Choices &c) | ||
522 | { | 94 | { | ||
523 | QString result = c.name(); | 95 | QString result = c.name(); | ||
524 | if (result.isEmpty()) { | 96 | if (result.isEmpty()) { | ||
525 | result = QLatin1String("Enum") + n; | 97 | result = QLatin1String("Enum") + n; | ||
526 | result[4] = result[4].toUpper(); | 98 | result[4] = result[4].toUpper(); | ||
527 | } | 99 | } | ||
528 | return result; | 100 | return result; | ||
529 | } | 101 | } | ||
530 | 102 | | |||
531 | static QString enumType(const CfgEntry *e, bool globalEnums) | 103 | QString enumType(const CfgEntry *e, bool globalEnums) | ||
532 | { | 104 | { | ||
533 | QString result = e->choices().name(); | 105 | QString result = e->choices.name(); | ||
534 | if (result.isEmpty()) { | 106 | if (result.isEmpty()) { | ||
535 | result = QLatin1String("Enum") + e->name(); | 107 | result = QLatin1String("Enum") + e->name; | ||
536 | if (!globalEnums) { | 108 | if (!globalEnums) { | ||
537 | result += QLatin1String("::type"); | 109 | result += QLatin1String("::type"); | ||
538 | } | 110 | } | ||
539 | result[4] = result[4].toUpper(); | 111 | result[4] = result[4].toUpper(); | ||
540 | } | 112 | } | ||
541 | return result; | 113 | return result; | ||
542 | } | 114 | } | ||
543 | 115 | | |||
544 | static QString enumTypeQualifier(const QString &n, const CfgEntry::Choices &c) | 116 | static QString enumTypeQualifier(const QString &n, const CfgEntry::Choices &c) | ||
545 | { | 117 | { | ||
546 | QString result = c.name(); | 118 | QString result = c.name(); | ||
547 | if (result.isEmpty()) { | 119 | if (result.isEmpty()) { | ||
548 | result = QLatin1String("Enum") + n + QLatin1String("::"); | 120 | result = QLatin1String("Enum") + n + QLatin1String("::"); | ||
549 | result[4] = result[4].toUpper(); | 121 | result[4] = result[4].toUpper(); | ||
550 | } else if (c.external()) { | 122 | } else if (c.external()) { | ||
551 | result = c.externalQualifier(); | 123 | result = c.externalQualifier(); | ||
552 | } else { | 124 | } else { | ||
553 | result.clear(); | 125 | result.clear(); | ||
554 | } | 126 | } | ||
555 | return result; | 127 | return result; | ||
556 | } | 128 | } | ||
557 | 129 | | |||
558 | static QString setFunction(const QString &n, const QString &className = QString()) | 130 | QString setFunction(const QString &n, const QString &className) | ||
559 | { | 131 | { | ||
560 | QString result = QLatin1String("set") + n; | 132 | QString result = QLatin1String("set") + n; | ||
561 | result[3] = result[3].toUpper(); | 133 | result[3] = result[3].toUpper(); | ||
562 | 134 | | |||
563 | if (!className.isEmpty()) { | 135 | if (!className.isEmpty()) { | ||
564 | result = className + QLatin1String("::") + result; | 136 | result = className + QLatin1String("::") + result; | ||
565 | } | 137 | } | ||
566 | return result; | 138 | return result; | ||
567 | } | 139 | } | ||
568 | 140 | | |||
569 | static QString changeSignalName(const QString &n) | 141 | QString changeSignalName(const QString &n) | ||
570 | { | 142 | { | ||
571 | return n+QStringLiteral("Changed"); | 143 | return n+QStringLiteral("Changed"); | ||
572 | } | 144 | } | ||
573 | 145 | | |||
574 | static QString getDefaultFunction(const QString &n, const QString &className = QString()) | 146 | QString getDefaultFunction(const QString &n, const QString &className) | ||
575 | { | 147 | { | ||
576 | QString result = QLatin1String("default") + n + QLatin1String("Value"); | 148 | QString result = QLatin1String("default") + n + QLatin1String("Value"); | ||
577 | result[7] = result[7].toUpper(); | 149 | result[7] = result[7].toUpper(); | ||
578 | 150 | | |||
579 | if (!className.isEmpty()) { | 151 | if (!className.isEmpty()) { | ||
580 | result = className + QLatin1String("::") + result; | 152 | result = className + QLatin1String("::") + result; | ||
581 | } | 153 | } | ||
582 | return result; | 154 | return result; | ||
583 | } | 155 | } | ||
584 | 156 | | |||
585 | static QString getFunction(const QString &n, const QString &className = QString()) | 157 | QString getFunction(const QString &n, const QString &className) | ||
586 | { | 158 | { | ||
587 | QString result = n; | 159 | QString result = n; | ||
588 | result[0] = result[0].toLower(); | 160 | result[0] = result[0].toLower(); | ||
589 | 161 | | |||
590 | if (!className.isEmpty()) { | 162 | if (!className.isEmpty()) { | ||
591 | result = className + QLatin1String("::") + result; | 163 | result = className + QLatin1String("::") + result; | ||
592 | } | 164 | } | ||
593 | return result; | 165 | return result; | ||
594 | } | 166 | } | ||
595 | 167 | | |||
596 | static void addQuotes(QString &s) | 168 | void addQuotes(QString &s) | ||
597 | { | 169 | { | ||
598 | if (!s.startsWith(QLatin1Char('"'))) { | 170 | if (!s.startsWith(QLatin1Char('"'))) { | ||
599 | s.prepend(QLatin1Char('"')); | 171 | s.prepend(QLatin1Char('"')); | ||
600 | } | 172 | } | ||
601 | if (!s.endsWith(QLatin1Char('"'))) { | 173 | if (!s.endsWith(QLatin1Char('"'))) { | ||
602 | s.append(QLatin1Char('"')); | 174 | s.append(QLatin1Char('"')); | ||
603 | } | 175 | } | ||
604 | } | 176 | } | ||
Show All 31 Lines | 204 | { | |||
636 | 208 | | |||
637 | msg = msg.simplified(); | 209 | msg = msg.simplified(); | ||
638 | if (msg.length() > 40) { | 210 | if (msg.length() > 40) { | ||
639 | return msg.left(37) + QLatin1String("..."); | 211 | return msg.left(37) + QLatin1String("..."); | ||
640 | } | 212 | } | ||
641 | return msg; | 213 | return msg; | ||
642 | } | 214 | } | ||
643 | 215 | | |||
644 | static QString filenameOnly(const QString &path) | 216 | QString filenameOnly(const QString &path) | ||
645 | { | 217 | { | ||
646 | int i = path.lastIndexOf(QRegExp(QStringLiteral("[/\\]"))); | 218 | int i = path.lastIndexOf(QRegExp(QStringLiteral("[/\\]"))); | ||
647 | if (i >= 0) { | 219 | if (i >= 0) { | ||
648 | return path.mid(i + 1); | 220 | return path.mid(i + 1); | ||
649 | } | 221 | } | ||
650 | return path; | 222 | return path; | ||
651 | } | 223 | } | ||
652 | 224 | | |||
653 | static QString signalEnumName(const QString &signalName) | 225 | QString signalEnumName(const QString &signalName) | ||
654 | { | 226 | { | ||
655 | QString result; | 227 | QString result; | ||
656 | result = QLatin1String("signal") + signalName; | 228 | result = QLatin1String("signal") + signalName; | ||
657 | result[6] = result[6].toUpper(); | 229 | result[6] = result[6].toUpper(); | ||
658 | 230 | | |||
659 | return result; | 231 | return result; | ||
660 | } | 232 | } | ||
661 | 233 | | |||
662 | static void preProcessDefault(QString &defaultValue, const QString &name, | 234 | static void preProcessDefault(QString &defaultValue, const QString &name, | ||
663 | const QString &type, | 235 | const QString &type, | ||
664 | const CfgEntry::Choices &choices, | 236 | const CfgEntry::Choices &choices, | ||
665 | QString &code, const CfgConfig &cfg) | 237 | QString &code, const KConfigXTParameters &cfg) | ||
666 | { | 238 | { | ||
667 | if (type == QLatin1String("String") && !defaultValue.isEmpty()) { | 239 | if (type == QLatin1String("String") && !defaultValue.isEmpty()) { | ||
668 | defaultValue = literalString(defaultValue); | 240 | defaultValue = literalString(defaultValue); | ||
669 | 241 | | |||
670 | } else if (type == QLatin1String("Path") && !defaultValue.isEmpty()) { | 242 | } else if (type == QLatin1String("Path") && !defaultValue.isEmpty()) { | ||
671 | defaultValue = literalString(defaultValue); | 243 | defaultValue = literalString(defaultValue); | ||
672 | } else if (type == QLatin1String("Url") && !defaultValue.isEmpty()) { | 244 | } else if (type == QLatin1String("Url") && !defaultValue.isEmpty()) { | ||
673 | // Use fromUserInput in order to support absolute paths and absolute urls, like KDE4's KUrl(QString) did. | 245 | // Use fromUserInput in order to support absolute paths and absolute urls, like KDE4's KUrl(QString) did. | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | 304 | for (it = defaults.constBegin(); it != defaults.constEnd(); ++it) { | |||
733 | cpp << " default" << name << ".append( " << *it << " );" | 305 | cpp << " default" << name << ".append( " << *it << " );" | ||
734 | << endl; | 306 | << endl; | ||
735 | } | 307 | } | ||
736 | } | 308 | } | ||
737 | defaultValue = QLatin1String("default") + name; | 309 | defaultValue = QLatin1String("default") + name; | ||
738 | } | 310 | } | ||
739 | } | 311 | } | ||
740 | 312 | | |||
741 | CfgEntry *parseEntry(const QString &group, const QDomElement &element, const CfgConfig &cfg) | 313 | CfgEntry *parseEntry(const QString &group, const QDomElement &element, const KConfigXTParameters &cfg) | ||
742 | { | 314 | { | ||
743 | bool defaultCode = false; | 315 | bool defaultCode = false; | ||
744 | QString type = element.attribute(QStringLiteral("type")); | 316 | QString type = element.attribute(QStringLiteral("type")); | ||
745 | QString name = element.attribute(QStringLiteral("name")); | 317 | QString name = element.attribute(QStringLiteral("name")); | ||
746 | QString key = element.attribute(QStringLiteral("key")); | 318 | QString key = element.attribute(QStringLiteral("key")); | ||
747 | QString hidden = element.attribute(QStringLiteral("hidden")); | 319 | QString hidden = element.attribute(QStringLiteral("hidden")); | ||
748 | QString labelContext; | 320 | QString labelContext; | ||
749 | QString label; | 321 | QString label; | ||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Line(s) | 538 | if (allNames.contains(name)) { | |||
973 | return nullptr; | 545 | return nullptr; | ||
974 | } | 546 | } | ||
975 | allNames.append(name); | 547 | allNames.append(name); | ||
976 | 548 | | |||
977 | if (!defaultCode) { | 549 | if (!defaultCode) { | ||
978 | preProcessDefault(defaultValue, name, type, choices, code, cfg); | 550 | preProcessDefault(defaultValue, name, type, choices, code, cfg); | ||
979 | } | 551 | } | ||
980 | 552 | | |||
981 | CfgEntry *result = new CfgEntry(group, type, key, name, labelContext, label, toolTipContext, toolTip, whatsThisContext, whatsThis, | 553 | CfgEntry *result = new CfgEntry(); | ||
982 | code, defaultValue, choices, signalList, | 554 | result->group = group; | ||
983 | hidden == QLatin1String("true")); | 555 | result->type = type; | ||
556 | result->key = key; | ||||
557 | result->name = name; | ||||
558 | result->labelContext = labelContext; | ||||
559 | result->label = label; | ||||
560 | result->toolTipContext = toolTipContext; | ||||
561 | result->toolTip = toolTip; | ||||
562 | result->whatsThisContext = whatsThisContext; | ||||
563 | result->whatsThis = whatsThis; | ||||
564 | result->code = code; | ||||
565 | result->defaultValue = defaultValue; | ||||
566 | result->choices = choices; | ||||
567 | result->signalList = signalList; | ||||
568 | result->hidden = hidden == QLatin1String("true"); | ||||
569 | | ||||
984 | if (!param.isEmpty()) { | 570 | if (!param.isEmpty()) { | ||
985 | result->setParam(param); | 571 | result->param = param; | ||
986 | result->setParamName(paramName); | 572 | result->paramName = paramName; | ||
987 | result->setParamType(paramType); | 573 | result->paramType = paramType; | ||
988 | result->setParamValues(paramValues); | 574 | result->paramValues = paramValues; | ||
989 | result->setParamDefaultValues(paramDefaultValues); | 575 | result->paramDefaultValues = paramDefaultValues; | ||
990 | result->setParamMax(paramMax); | 576 | result->paramMax = paramMax; | ||
991 | } | 577 | } | ||
992 | result->setMinValue(minValue); | 578 | result->min = minValue; | ||
993 | result->setMaxValue(maxValue); | 579 | result->max = maxValue; | ||
994 | 580 | | |||
995 | return result; | 581 | return result; | ||
996 | } | 582 | } | ||
997 | 583 | | |||
998 | static bool isUnsigned(const QString &type) | 584 | static bool isUnsigned(const QString &type) | ||
999 | { | 585 | { | ||
1000 | if (type == QLatin1String("UInt")) { | 586 | if (type == QLatin1String("UInt")) { | ||
1001 | return true; | 587 | return true; | ||
▲ Show 20 Lines • Show All 168 Lines • ▼ Show 20 Line(s) | 755 | { | |||
1170 | QString t; | 756 | QString t; | ||
1171 | 757 | | |||
1172 | t = type; | 758 | t = type; | ||
1173 | t.replace(0, 1, t.left(1).toUpper()); | 759 | t.replace(0, 1, t.left(1).toUpper()); | ||
1174 | 760 | | |||
1175 | return t; | 761 | return t; | ||
1176 | } | 762 | } | ||
1177 | 763 | | |||
1178 | static QString itemDeclaration(const CfgEntry *e, const CfgConfig &cfg) | 764 | QString itemDeclaration(const CfgEntry *e, const KConfigXTParameters &cfg) | ||
1179 | { | 765 | { | ||
1180 | if (cfg.itemAccessors) { | 766 | if (cfg.itemAccessors) { | ||
1181 | return QString(); | 767 | return QString(); | ||
1182 | } | 768 | } | ||
1183 | 769 | | |||
1184 | QString type; | 770 | QString type; | ||
1185 | if (!e->signalList().isEmpty()) { | 771 | if (!e->signalList.isEmpty()) { | ||
1186 | type = QStringLiteral("KConfigCompilerSignallingItem"); | 772 | type = QStringLiteral("KConfigCompilerSignallingItem"); | ||
1187 | } else { | 773 | } else { | ||
1188 | type = cfg.inherits + "::Item" + itemType(e->type()); | 774 | type = cfg.inherits + "::Item" + itemType(e->type); | ||
1189 | } | 775 | } | ||
1190 | 776 | | |||
1191 | QString fCap = e->name(); | 777 | QString fCap = e->name; | ||
1192 | fCap[0] = fCap[0].toUpper(); | 778 | fCap[0] = fCap[0].toUpper(); | ||
1193 | return " " + type + " *item" + fCap + | 779 | return " " + type + " *item" + fCap + | ||
1194 | ( (!e->param().isEmpty())?(QStringLiteral("[%1]").arg(e->paramMax()+1)) : QString()) + ";\n"; | 780 | ( (!e->param.isEmpty())?(QStringLiteral("[%1]").arg(e->paramMax+1)) : QString()) + ";\n"; | ||
1195 | } | 781 | } | ||
1196 | 782 | | |||
1197 | // returns the name of an item variable | 783 | // returns the name of an item variable | ||
1198 | // use itemPath to know the full path | 784 | // use itemPath to know the full path | ||
1199 | // like using d-> in case of dpointer | 785 | // like using d-> in case of dpointer | ||
1200 | static QString itemVar(const CfgEntry *e, const CfgConfig &cfg) | 786 | QString itemVar(const CfgEntry *e, const KConfigXTParameters &cfg) | ||
1201 | { | 787 | { | ||
1202 | QString result; | 788 | QString result; | ||
1203 | if (cfg.itemAccessors) { | 789 | if (cfg.itemAccessors) { | ||
1204 | if (!cfg.dpointer) { | 790 | if (!cfg.dpointer) { | ||
1205 | result = 'm' + e->name() + "Item"; | 791 | result = 'm' + e->name + "Item"; | ||
1206 | result[1] = result[1].toUpper(); | 792 | result[1] = result[1].toUpper(); | ||
1207 | } else { | 793 | } else { | ||
1208 | result = e->name() + "Item"; | 794 | result = e->name + "Item"; | ||
1209 | result[0] = result[0].toLower(); | 795 | result[0] = result[0].toLower(); | ||
1210 | } | 796 | } | ||
1211 | } else { | 797 | } else { | ||
1212 | result = "item" + e->name(); | 798 | result = "item" + e->name; | ||
1213 | result[4] = result[4].toUpper(); | 799 | result[4] = result[4].toUpper(); | ||
1214 | } | 800 | } | ||
1215 | return result; | 801 | return result; | ||
1216 | } | 802 | } | ||
1217 | 803 | | |||
1218 | static QString itemPath(const CfgEntry *e, const CfgConfig &cfg) | 804 | QString itemPath(const CfgEntry *e, const KConfigXTParameters &cfg) | ||
1219 | { | 805 | { | ||
1220 | QString result; | 806 | QString result; | ||
1221 | if (cfg.dpointer) { | 807 | if (cfg.dpointer) { | ||
1222 | result = "d->" + itemVar(e, cfg); | 808 | result = "d->" + itemVar(e, cfg); | ||
1223 | } else { | 809 | } else { | ||
1224 | result = itemVar(e, cfg); | 810 | result = itemVar(e, cfg); | ||
1225 | } | 811 | } | ||
1226 | return result; | 812 | return result; | ||
1227 | } | 813 | } | ||
1228 | 814 | | |||
1229 | QString newItem(const CfgEntry* entry, const QString &key, const QString& defaultValue, | 815 | QString newItem(const CfgEntry* entry, const QString &key, const QString& defaultValue, | ||
1230 | const CfgConfig &cfg, const QString ¶m = QString()) { | 816 | const KConfigXTParameters &cfg, const QString ¶m) { | ||
1231 | 817 | | |||
1232 | QList<Signal> sigs = entry->signalList(); | 818 | QList<Signal> sigs = entry->signalList; | ||
1233 | QString t; | 819 | QString t; | ||
1234 | if (!sigs.isEmpty()) { | 820 | if (!sigs.isEmpty()) { | ||
1235 | t += QLatin1String("new KConfigCompilerSignallingItem("); | 821 | t += QLatin1String("new KConfigCompilerSignallingItem("); | ||
1236 | } | 822 | } | ||
1237 | t += "new "+ cfg.inherits + "::Item" + itemType(entry->type()) + "( currentGroup(), " | 823 | t += "new "+ cfg.inherits + "::Item" + itemType(entry->type) + "( currentGroup(), " | ||
1238 | + key + ", " + varPath( entry->name(), cfg ) + param; | 824 | + key + ", " + varPath( entry->name, cfg ) + param; | ||
1239 | 825 | | |||
1240 | if (entry->type() == QLatin1String("Enum")) { | 826 | if (entry->type == QLatin1String("Enum")) { | ||
1241 | t += ", values" + entry->name(); | 827 | t += ", values" + entry->name; | ||
1242 | } | 828 | } | ||
1243 | if (!defaultValue.isEmpty()) { | 829 | if (!defaultValue.isEmpty()) { | ||
1244 | t += QLatin1String(", ") + defaultValue; | 830 | t += QLatin1String(", ") + defaultValue; | ||
1245 | } | 831 | } | ||
1246 | t += QLatin1String(" )"); | 832 | t += QLatin1String(" )"); | ||
1247 | 833 | | |||
1248 | if (!sigs.isEmpty()) { | 834 | if (!sigs.isEmpty()) { | ||
1249 | t += QLatin1String(", this, notifyFunction, "); | 835 | t += QLatin1String(", this, notifyFunction, "); | ||
1250 | //append the signal flags | 836 | //append the signal flags | ||
1251 | for (int i = 0; i < sigs.size(); ++i) { | 837 | for (int i = 0; i < sigs.size(); ++i) { | ||
1252 | if (i != 0) | 838 | if (i != 0) | ||
1253 | t += QLatin1String(" | "); | 839 | t += QLatin1String(" | "); | ||
1254 | t += signalEnumName(sigs[i].name); | 840 | t += signalEnumName(sigs[i].name); | ||
1255 | } | 841 | } | ||
1256 | t += QLatin1String(")"); | 842 | t += QLatin1String(")"); | ||
1257 | } | 843 | } | ||
1258 | t += QLatin1String(";"); | 844 | t += QLatin1String(";"); | ||
1259 | return t; | 845 | return t; | ||
1260 | } | 846 | } | ||
1261 | 847 | | |||
1262 | QString paramString(const QString &s, const CfgEntry *e, int i) | 848 | QString paramString(const QString &s, const CfgEntry *e, int i) | ||
1263 | { | 849 | { | ||
1264 | QString result = s; | 850 | QString result = s; | ||
1265 | QString needle = "$(" + e->param() + ')'; | 851 | QString needle = "$(" + e->param + ')'; | ||
1266 | if (result.contains(needle)) { | 852 | if (result.contains(needle)) { | ||
1267 | QString tmp; | 853 | QString tmp; | ||
1268 | if (e->paramType() == QLatin1String("Enum")) { | 854 | if (e->paramType == QLatin1String("Enum")) { | ||
1269 | tmp = e->paramValues().at(i); | 855 | tmp = e->paramValues.at(i); | ||
1270 | } else { | 856 | } else { | ||
1271 | tmp = QString::number(i); | 857 | tmp = QString::number(i); | ||
1272 | } | 858 | } | ||
1273 | 859 | | |||
1274 | result.replace(needle, tmp); | 860 | result.replace(needle, tmp); | ||
1275 | } | 861 | } | ||
1276 | return result; | 862 | return result; | ||
1277 | } | 863 | } | ||
Show All 13 Lines | 866 | { | |||
1291 | } | 877 | } | ||
1292 | if (arguments.isEmpty()) { | 878 | if (arguments.isEmpty()) { | ||
1293 | return "QStringLiteral( \"" + group + "\" )"; | 879 | return "QStringLiteral( \"" + group + "\" )"; | ||
1294 | } | 880 | } | ||
1295 | 881 | | |||
1296 | return "QStringLiteral( \"" + paramString + "\" )" + arguments; | 882 | return "QStringLiteral( \"" + paramString + "\" )" + arguments; | ||
1297 | } | 883 | } | ||
1298 | 884 | | |||
1299 | QString translatedString(const CfgConfig &cfg, const QString &string, const QString &context = QString(), const QString ¶m = QString(), const QString ¶mValue = QString()) | 885 | QString translatedString(const KConfigXTParameters &cfg, const QString &string, const QString &context, const QString ¶m, const QString ¶mValue) | ||
1300 | { | 886 | { | ||
1301 | QString result; | 887 | QString result; | ||
1302 | 888 | | |||
1303 | switch (cfg.translationSystem) { | 889 | switch (cfg.translationSystem) { | ||
1304 | case CfgConfig::QtTranslation: | 890 | case KConfigXTParameters::QtTranslation: | ||
1305 | if (!context.isEmpty()) { | 891 | if (!context.isEmpty()) { | ||
1306 | result += "/*: " + context + " */ QCoreApplication::translate(\""; | 892 | result += "/*: " + context + " */ QCoreApplication::translate(\""; | ||
1307 | } else { | 893 | } else { | ||
1308 | result += QLatin1String("QCoreApplication::translate(\""); | 894 | result += QLatin1String("QCoreApplication::translate(\""); | ||
1309 | } | 895 | } | ||
1310 | result += cfg.className + "\", "; | 896 | result += cfg.className + "\", "; | ||
1311 | break; | 897 | break; | ||
1312 | 898 | | |||
1313 | case CfgConfig::KdeTranslation: | 899 | case KConfigXTParameters::KdeTranslation: | ||
1314 | if (!cfg.translationDomain.isEmpty() && !context.isEmpty()) { | 900 | if (!cfg.translationDomain.isEmpty() && !context.isEmpty()) { | ||
1315 | result += "i18ndc(" + quoteString(cfg.translationDomain) + ", " + quoteString(context) + ", "; | 901 | result += "i18ndc(" + quoteString(cfg.translationDomain) + ", " + quoteString(context) + ", "; | ||
1316 | } else if (!cfg.translationDomain.isEmpty()) { | 902 | } else if (!cfg.translationDomain.isEmpty()) { | ||
1317 | result += "i18nd(" + quoteString(cfg.translationDomain) + ", "; | 903 | result += "i18nd(" + quoteString(cfg.translationDomain) + ", "; | ||
1318 | } else if (!context.isEmpty()) { | 904 | } else if (!context.isEmpty()) { | ||
1319 | result += "i18nc(" + quoteString(context) + ", "; | 905 | result += "i18nc(" + quoteString(context) + ", "; | ||
1320 | } else { | 906 | } else { | ||
1321 | result += QLatin1String("i18n("); | 907 | result += QLatin1String("i18n("); | ||
Show All 10 Lines | |||||
1332 | } | 918 | } | ||
1333 | 919 | | |||
1334 | result += ')'; | 920 | result += ')'; | ||
1335 | 921 | | |||
1336 | return result; | 922 | return result; | ||
1337 | } | 923 | } | ||
1338 | 924 | | |||
1339 | /* int i is the value of the parameter */ | 925 | /* int i is the value of the parameter */ | ||
1340 | QString userTextsFunctions(CfgEntry *e, const CfgConfig &cfg, QString itemVarStr = QString(), const QString &i = QString()) | 926 | QString userTextsFunctions(CfgEntry *e, const KConfigXTParameters &cfg, QString itemVarStr, const QString &i) | ||
1341 | { | 927 | { | ||
1342 | QString txt; | 928 | QString txt; | ||
1343 | if (itemVarStr.isNull()) { | 929 | if (itemVarStr.isNull()) { | ||
1344 | itemVarStr = itemPath(e, cfg); | 930 | itemVarStr = itemPath(e, cfg); | ||
1345 | } | 931 | } | ||
1346 | if (!e->label().isEmpty()) { | 932 | if (!e->label.isEmpty()) { | ||
1347 | txt += " " + itemVarStr + "->setLabel( "; | 933 | txt += " " + itemVarStr + "->setLabel( "; | ||
1348 | txt += translatedString(cfg, e->label(), e->labelContext(), e->param(), i); | 934 | txt += translatedString(cfg, e->label, e->labelContext, e->param, i); | ||
1349 | txt += QLatin1String(" );\n"); | 935 | txt += QLatin1String(" );\n"); | ||
1350 | } | 936 | } | ||
1351 | if (!e->toolTip().isEmpty()) { | 937 | if (!e->toolTip.isEmpty()) { | ||
1352 | txt += " " + itemVarStr + "->setToolTip( "; | 938 | txt += " " + itemVarStr + "->setToolTip( "; | ||
1353 | txt += translatedString(cfg, e->toolTip(), e->toolTipContext(), e->param(), i); | 939 | txt += translatedString(cfg, e->toolTip, e->toolTipContext, e->param, i); | ||
1354 | txt += QLatin1String(" );\n"); | 940 | txt += QLatin1String(" );\n"); | ||
1355 | } | 941 | } | ||
1356 | if (!e->whatsThis().isEmpty()) { | 942 | if (!e->whatsThis.isEmpty()) { | ||
1357 | txt += " " + itemVarStr + "->setWhatsThis( "; | 943 | txt += " " + itemVarStr + "->setWhatsThis( "; | ||
1358 | txt += translatedString(cfg, e->whatsThis(), e->whatsThisContext(), e->param(), i); | 944 | txt += translatedString(cfg, e->whatsThis, e->whatsThisContext, e->param, i); | ||
1359 | txt += QLatin1String(" );\n"); | 945 | txt += QLatin1String(" );\n"); | ||
1360 | } | 946 | } | ||
1361 | return txt; | 947 | return txt; | ||
1362 | } | 948 | } | ||
1363 | 949 | | |||
1364 | // returns the member accesor implementation | 950 | // returns the member accesor implementation | ||
1365 | // which should go in the h file if inline | 951 | // which should go in the h file if inline | ||
1366 | // or the cpp file if not inline | 952 | // or the cpp file if not inline | ||
1367 | QString memberAccessorBody(CfgEntry *e, bool globalEnums, const CfgConfig &cfg) | 953 | QString memberAccessorBody(CfgEntry *e, bool globalEnums, const KConfigXTParameters &cfg) | ||
1368 | { | 954 | { | ||
1369 | QString result; | 955 | QString result; | ||
1370 | QTextStream out(&result, QIODevice::WriteOnly); | 956 | QTextStream out(&result, QIODevice::WriteOnly); | ||
1371 | QString n = e->name(); | 957 | QString n = e->name; | ||
1372 | QString t = e->type(); | 958 | QString t = e->type; | ||
1373 | bool useEnumType = cfg.useEnumTypes && t == QLatin1String("Enum"); | 959 | bool useEnumType = cfg.useEnumTypes && t == QLatin1String("Enum"); | ||
1374 | 960 | | |||
1375 | out << "return "; | 961 | out << "return "; | ||
1376 | if (useEnumType) { | 962 | if (useEnumType) { | ||
1377 | out << "static_cast<" << enumType(e, globalEnums) << ">("; | 963 | out << "static_cast<" << enumType(e, globalEnums) << ">("; | ||
1378 | } | 964 | } | ||
1379 | out << This << varPath(n, cfg); | 965 | out << This << varPath(n, cfg); | ||
1380 | if (!e->param().isEmpty()) { | 966 | if (!e->param.isEmpty()) { | ||
1381 | out << "[i]"; | 967 | out << "[i]"; | ||
1382 | } | 968 | } | ||
1383 | if (useEnumType) { | 969 | if (useEnumType) { | ||
1384 | out << ")"; | 970 | out << ")"; | ||
1385 | } | 971 | } | ||
1386 | out << ";" << endl; | 972 | out << ";" << endl; | ||
1387 | 973 | | |||
1388 | return result; | 974 | return result; | ||
1389 | } | 975 | } | ||
1390 | 976 | | |||
1391 | // returns the member mutator implementation | 977 | // returns the member mutator implementation | ||
1392 | // which should go in the h file if inline | 978 | // which should go in the h file if inline | ||
1393 | // or the cpp file if not inline | 979 | // or the cpp file if not inline | ||
1394 | 980 | | |||
1395 | void addDebugMethod(QTextStream &out, const CfgConfig &cfg, const QString &n) | 981 | void addDebugMethod(QTextStream &out, const KConfigXTParameters &cfg, const QString &n) | ||
1396 | { | 982 | { | ||
1397 | if (cfg.qCategoryLoggingName.isEmpty()) { | 983 | if (cfg.qCategoryLoggingName.isEmpty()) { | ||
1398 | out << " qDebug() << \"" << setFunction(n); | 984 | out << " qDebug() << \"" << setFunction(n); | ||
1399 | } else { | 985 | } else { | ||
1400 | out << " qCDebug(" << cfg.qCategoryLoggingName << ") << \"" << setFunction(n); | 986 | out << " qCDebug(" << cfg.qCategoryLoggingName << ") << \"" << setFunction(n); | ||
1401 | } | 987 | } | ||
1402 | } | 988 | } | ||
1403 | 989 | | |||
1404 | QString memberMutatorBody(CfgEntry *e, const CfgConfig &cfg) | 990 | QString memberMutatorBody(CfgEntry *e, const KConfigXTParameters &cfg) | ||
1405 | { | 991 | { | ||
1406 | QString result; | 992 | QString result; | ||
1407 | QTextStream out(&result, QIODevice::WriteOnly); | 993 | QTextStream out(&result, QIODevice::WriteOnly); | ||
1408 | QString n = e->name(); | 994 | QString n = e->name; | ||
1409 | QString t = e->type(); | 995 | QString t = e->type; | ||
1410 | 996 | | |||
1411 | if (!e->minValue().isEmpty()) { | 997 | if (!e->min.isEmpty()) { | ||
1412 | if (e->minValue() != QLatin1String("0") || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) | 998 | if (e->min != QLatin1String("0") || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) | ||
1413 | out << "if (v < " << e->minValue() << ")" << endl; | 999 | out << "if (v < " << e->min << ")" << endl; | ||
1414 | out << "{" << endl; | 1000 | out << "{" << endl; | ||
1415 | addDebugMethod(out, cfg, n); | 1001 | addDebugMethod(out, cfg, n); | ||
1416 | out << ": value \" << v << \" is less than the minimum value of "; | 1002 | out << ": value \" << v << \" is less than the minimum value of "; | ||
1417 | out << e->minValue() << "\";" << endl; | 1003 | out << e->min << "\";" << endl; | ||
1418 | out << " v = " << e->minValue() << ";" << endl; | 1004 | out << " v = " << e->min << ";" << endl; | ||
1419 | out << "}" << endl; | 1005 | out << "}" << endl; | ||
1420 | } | 1006 | } | ||
1421 | } | 1007 | } | ||
1422 | 1008 | | |||
1423 | if (!e->maxValue().isEmpty()) { | 1009 | if (!e->max.isEmpty()) { | ||
1424 | out << endl << "if (v > " << e->maxValue() << ")" << endl; | 1010 | out << endl << "if (v > " << e->max << ")" << endl; | ||
1425 | out << "{" << endl; | 1011 | out << "{" << endl; | ||
1426 | addDebugMethod(out, cfg, n); | 1012 | addDebugMethod(out, cfg, n); | ||
1427 | out << ": value \" << v << \" is greater than the maximum value of "; | 1013 | out << ": value \" << v << \" is greater than the maximum value of "; | ||
1428 | out << e->maxValue() << "\";" << endl; | 1014 | out << e->max << "\";" << endl; | ||
1429 | out << " v = " << e->maxValue() << ";" << endl; | 1015 | out << " v = " << e->max << ";" << endl; | ||
1430 | out << "}" << endl << endl; | 1016 | out << "}" << endl << endl; | ||
1431 | } | 1017 | } | ||
1432 | 1018 | | |||
1433 | const QString varExpression = This + varPath(n, cfg) + (e->param().isEmpty() ? QString() : QStringLiteral("[i]")); | 1019 | const QString varExpression = This + varPath(n, cfg) + (e->param.isEmpty() ? QString() : QStringLiteral("[i]")); | ||
1434 | 1020 | | |||
1435 | const bool hasBody = !e->signalList().empty() || cfg.generateProperties; | 1021 | const bool hasBody = !e->signalList.empty() || cfg.generateProperties; | ||
1436 | out << "if ("; | 1022 | out << "if ("; | ||
1437 | if (hasBody) { | 1023 | if (hasBody) { | ||
1438 | out << "v != " << varExpression << " && "; | 1024 | out << "v != " << varExpression << " && "; | ||
1439 | } | 1025 | } | ||
1440 | out << "!" << This << "isImmutable( QStringLiteral( \""; | 1026 | out << "!" << This << "isImmutable( QStringLiteral( \""; | ||
1441 | if (!e->param().isEmpty()) { | 1027 | if (!e->param.isEmpty()) { | ||
1442 | out << e->paramName().replace("$(" + e->param() + ")", QLatin1String("%1")) << "\" ).arg( "; | 1028 | out << e->paramName.replace("$(" + e->param + ")", QLatin1String("%1")) << "\" ).arg( "; | ||
1443 | if (e->paramType() == QLatin1String("Enum")) { | 1029 | if (e->paramType == QLatin1String("Enum")) { | ||
1444 | out << "QLatin1String( "; | 1030 | out << "QLatin1String( "; | ||
1445 | 1031 | | |||
1446 | if (cfg.globalEnums) { | 1032 | if (cfg.globalEnums) { | ||
1447 | out << enumName(e->param()) << "ToString[i]"; | 1033 | out << enumName(e->param) << "ToString[i]"; | ||
1448 | } else { | 1034 | } else { | ||
1449 | out << enumName(e->param()) << "::enumToString[i]"; | 1035 | out << enumName(e->param) << "::enumToString[i]"; | ||
1450 | } | 1036 | } | ||
1451 | 1037 | | |||
1452 | out << " )"; | 1038 | out << " )"; | ||
1453 | } else { | 1039 | } else { | ||
1454 | out << "i"; | 1040 | out << "i"; | ||
1455 | } | 1041 | } | ||
1456 | out << " )"; | 1042 | out << " )"; | ||
1457 | } else { | 1043 | } else { | ||
1458 | out << n << "\" )"; | 1044 | out << n << "\" )"; | ||
1459 | } | 1045 | } | ||
1460 | out << " ))" << (hasBody ? " {" : "") << endl; | 1046 | out << " ))" << (hasBody ? " {" : "") << endl; | ||
1461 | out << " " << varExpression << " = v;" << endl; | 1047 | out << " " << varExpression << " = v;" << endl; | ||
1462 | 1048 | | |||
1463 | const auto listSignal = e->signalList(); | 1049 | const auto listSignal = e->signalList; | ||
1464 | for (const Signal &signal : listSignal) { | 1050 | for (const Signal &signal : listSignal) { | ||
1465 | if (signal.modify) { | 1051 | if (signal.modify) { | ||
1466 | out << " Q_EMIT " << This << signal.name << "();" << endl; | 1052 | out << " Q_EMIT " << This << signal.name << "();" << endl; | ||
1467 | } else { | 1053 | } else { | ||
1468 | out << " " << This << varPath(QStringLiteral("settingsChanged"), cfg) << " |= " << signalEnumName(signal.name) << ";" << endl; | 1054 | out << " " << This << varPath(QStringLiteral("settingsChanged"), cfg) << " |= " << signalEnumName(signal.name) << ";" << endl; | ||
1469 | } | 1055 | } | ||
1470 | } | 1056 | } | ||
1471 | if (hasBody) { | 1057 | if (hasBody) { | ||
1472 | out << "}" << endl; | 1058 | out << "}" << endl; | ||
1473 | } | 1059 | } | ||
1474 | 1060 | | |||
1475 | return result; | 1061 | return result; | ||
1476 | } | 1062 | } | ||
1477 | 1063 | | |||
1478 | // returns the member get default implementation | 1064 | // returns the member get default implementation | ||
1479 | // which should go in the h file if inline | 1065 | // which should go in the h file if inline | ||
1480 | // or the cpp file if not inline | 1066 | // or the cpp file if not inline | ||
1481 | QString memberGetDefaultBody(CfgEntry *e) | 1067 | QString memberGetDefaultBody(CfgEntry *e) | ||
1482 | { | 1068 | { | ||
1483 | QString result = e->code(); | 1069 | QString result = e->code; | ||
1484 | QTextStream out(&result, QIODevice::WriteOnly); | 1070 | QTextStream out(&result, QIODevice::WriteOnly); | ||
1485 | out << endl; | 1071 | out << endl; | ||
1486 | 1072 | | |||
1487 | if (!e->param().isEmpty()) { | 1073 | if (!e->param.isEmpty()) { | ||
1488 | out << " switch (i) {" << endl; | 1074 | out << " switch (i) {" << endl; | ||
1489 | for (int i = 0; i <= e->paramMax(); ++i) { | 1075 | for (int i = 0; i <= e->paramMax; ++i) { | ||
1490 | if (!e->paramDefaultValue(i).isEmpty()) { | 1076 | if (!e->paramDefaultValues[i].isEmpty()) { | ||
1491 | out << " case " << i << ": return " << e->paramDefaultValue(i) << ';' << endl; | 1077 | out << " case " << i << ": return " << e->paramDefaultValues[i] << ';' << endl; | ||
1492 | } | 1078 | } | ||
1493 | } | 1079 | } | ||
1494 | out << " default:" << endl; | 1080 | out << " default:" << endl; | ||
1495 | out << " return " << e->defaultValue().replace("$(" + e->param() + ')', QLatin1String("i")) << ';' << endl; | 1081 | out << " return " << e->defaultValue.replace("$(" + e->param + ')', QLatin1String("i")) << ';' << endl; | ||
1496 | out << " }" << endl; | 1082 | out << " }" << endl; | ||
1497 | } else { | 1083 | } else { | ||
1498 | out << " return " << e->defaultValue() << ';'; | 1084 | out << " return " << e->defaultValue << ';'; | ||
1499 | } | 1085 | } | ||
1500 | 1086 | | |||
1501 | return result; | 1087 | return result; | ||
1502 | } | 1088 | } | ||
1503 | 1089 | | |||
1504 | // returns the item accesor implementation | 1090 | // returns the item accesor implementation | ||
1505 | // which should go in the h file if inline | 1091 | // which should go in the h file if inline | ||
1506 | // or the cpp file if not inline | 1092 | // or the cpp file if not inline | ||
1507 | QString itemAccessorBody(CfgEntry *e, const CfgConfig &cfg) | 1093 | QString itemAccessorBody(CfgEntry *e, const KConfigXTParameters &cfg) | ||
1508 | { | 1094 | { | ||
1509 | QString result; | 1095 | QString result; | ||
1510 | QTextStream out(&result, QIODevice::WriteOnly); | 1096 | QTextStream out(&result, QIODevice::WriteOnly); | ||
1511 | 1097 | | |||
1512 | out << "return " << itemPath(e, cfg); | 1098 | out << "return " << itemPath(e, cfg); | ||
1513 | if (!e->param().isEmpty()) { | 1099 | if (!e->param.isEmpty()) { | ||
1514 | out << "[i]"; | 1100 | out << "[i]"; | ||
1515 | } | 1101 | } | ||
1516 | out << ";" << endl; | 1102 | out << ";" << endl; | ||
1517 | 1103 | | |||
1518 | return result; | 1104 | return result; | ||
1519 | } | 1105 | } | ||
1520 | 1106 | | |||
1521 | //indents text adding X spaces per line | 1107 | //indents text adding X spaces per line | ||
1522 | QString indent(QString text, int spaces) | 1108 | QString indent(QString text, int spaces) | ||
1523 | { | 1109 | { | ||
1524 | QString result; | 1110 | QString result; | ||
1525 | QTextStream out(&result, QIODevice::WriteOnly); | 1111 | QTextStream out(&result, QIODevice::WriteOnly); | ||
1526 | QTextStream in(&text, QIODevice::ReadOnly); | 1112 | QTextStream in(&text, QIODevice::ReadOnly); | ||
1527 | QString currLine; | 1113 | QString currLine; | ||
1528 | while (!in.atEnd()) { | 1114 | while (!in.atEnd()) { | ||
1529 | currLine = in.readLine(); | 1115 | currLine = in.readLine(); | ||
1530 | if (!currLine.isEmpty()) | 1116 | if (!currLine.isEmpty()) | ||
1531 | for (int i = 0; i < spaces; i++) { | 1117 | for (int i = 0; i < spaces; i++) { | ||
1532 | out << " "; | 1118 | out << " "; | ||
1533 | } | 1119 | } | ||
1534 | out << currLine << endl; | 1120 | out << currLine << endl; | ||
1535 | } | 1121 | } | ||
1536 | return result; | 1122 | return result; | ||
1537 | } | 1123 | } | ||
1538 | 1124 | | |||
1539 | // adds as many 'namespace foo {' lines to p_out as | | |||
1540 | // there are namespaces in p_ns | | |||
1541 | void beginNamespaces(const QString &p_ns, QTextStream &p_out) | | |||
1542 | { | | |||
1543 | if (!p_ns.isEmpty()) { | | |||
1544 | const QStringList nameSpaces = p_ns.split(QStringLiteral("::")); | | |||
1545 | for (const QString &ns : nameSpaces) { | | |||
1546 | p_out << "namespace " << ns << " {" << endl; | | |||
1547 | } | | |||
1548 | p_out << endl; | | |||
1549 | } | | |||
1550 | } | | |||
1551 | | ||||
1552 | // adds as many '}' lines to p_out as | | |||
1553 | // there are namespaces in p_ns | | |||
1554 | void endNamespaces(const QString &p_ns, QTextStream &p_out) | | |||
1555 | { | | |||
1556 | if (!p_ns.isEmpty()) { | | |||
1557 | const int namespaceCount = p_ns.count(QStringLiteral("::")) + 1; | | |||
1558 | for (int i = 0; i < namespaceCount; ++i) { | | |||
1559 | p_out << "}" << endl; | | |||
1560 | } | | |||
1561 | p_out << endl; | | |||
1562 | } | | |||
1563 | } | | |||
1564 | | ||||
1565 | int main(int argc, char **argv) | 1125 | int main(int argc, char **argv) | ||
ervin: Space before & not after | |||||
1566 | { | 1126 | { | ||
1567 | QCoreApplication app(argc, argv); | 1127 | QCoreApplication app(argc, argv); | ||
1568 | app.setApplicationName(QStringLiteral("kconfig_compiler")); | 1128 | app.setApplicationName(QStringLiteral("kconfig_compiler")); | ||
1569 | app.setApplicationVersion(QStringLiteral(KCONFIG_VERSION_STRING)); | 1129 | app.setApplicationVersion(QStringLiteral(KCONFIG_VERSION_STRING)); | ||
1570 | 1130 | | |||
1571 | validNameRegexp = new QRegExp(QStringLiteral("[a-zA-Z_][a-zA-Z0-9_]*")); | 1131 | validNameRegexp = new QRegExp(QStringLiteral("[a-zA-Z_][a-zA-Z0-9_]*")); | ||
1572 | 1132 | | |||
1573 | QString inputFilename, codegenFilename; | 1133 | QString inputFilename, codegenFilename; | ||
Show All 40 Lines | 1169 | return 1; | |||
1614 | QString baseDir = parser.value(targetDirectoryOption); | 1174 | QString baseDir = parser.value(targetDirectoryOption); | ||
1615 | 1175 | | |||
1616 | #ifdef Q_OS_WIN | 1176 | #ifdef Q_OS_WIN | ||
1617 | if (!baseDir.endsWith('/') && !baseDir.endsWith('\\')) | 1177 | if (!baseDir.endsWith('/') && !baseDir.endsWith('\\')) | ||
1618 | #else | 1178 | #else | ||
1619 | if (!baseDir.endsWith('/')) | 1179 | if (!baseDir.endsWith('/')) | ||
1620 | #endif | 1180 | #endif | ||
1621 | baseDir.append("/"); | 1181 | baseDir.append("/"); | ||
1622 | 1182 | | |||
1623 | if (!codegenFilename.endsWith(QLatin1String(".kcfgc"))) { | 1183 | KConfigXTParameters cfg = KConfigXTParameters(codegenFilename); | ||
dfaure: it's shorter and simpler to write KConfigXTParameters cfg(codegenFilename);
| |||||
1624 | cerr << "Codegen options file must have extension .kcfgc" << endl; | | |||
1625 | return 1; | | |||
1626 | } | | |||
1627 | QString baseName = QFileInfo(codegenFilename).fileName(); | | |||
1628 | baseName = baseName.left(baseName.length() - 6); | | |||
1629 | | ||||
1630 | CfgConfig cfg = CfgConfig(codegenFilename); | | |||
1631 | 1184 | | |||
1632 | QFile input(inputFilename); | 1185 | QFile input(inputFilename); | ||
dfaure: const ... ? | |||||
that was a bit harder than I want, but done. Inside of the code generation there was code that manipulated the ParseResult. I think this is one of the good spots that show that this rewrite is really needed. tcanabrava: that was a bit harder than I want, but done. Inside of the code generation there was code that… | |||||
aaaaaand no, this introduced regressions, I'll try to solve it later but it's not as simple. this will unfortunately still be modified inside of the generator files. :/ tcanabrava: aaaaaand no, this introduced regressions, I'll try to solve it later but it's not as simple. | |||||
1633 | 1186 | | |||
1634 | QDomDocument doc; | 1187 | QDomDocument doc; | ||
1635 | QString errorMsg; | 1188 | QString errorMsg; | ||
1636 | int errorRow; | 1189 | int errorRow; | ||
1637 | int errorCol; | 1190 | int errorCol; | ||
1638 | if (!doc.setContent(&input, &errorMsg, &errorRow, &errorCol)) { | 1191 | if (!doc.setContent(&input, &errorMsg, &errorRow, &errorCol)) { | ||
1639 | cerr << "Unable to load document." << endl; | 1192 | cerr << "Unable to load document." << endl; | ||
1640 | cerr << "Parse error in " << inputFilename << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl; | 1193 | cerr << "Parse error in " << inputFilename << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl; | ||
1641 | return 1; | 1194 | return 1; | ||
1642 | } | 1195 | } | ||
1643 | 1196 | | |||
1644 | QDomElement cfgElement = doc.documentElement(); | 1197 | QDomElement cfgElement = doc.documentElement(); | ||
1645 | 1198 | | |||
1646 | if (cfgElement.isNull()) { | 1199 | if (cfgElement.isNull()) { | ||
1647 | cerr << "No document in kcfg file" << endl; | 1200 | cerr << "No document in kcfg file" << endl; | ||
1648 | return 1; | 1201 | return 1; | ||
1649 | } | 1202 | } | ||
1650 | 1203 | | |||
1651 | QString cfgFileName; | 1204 | ParseResult parseResult; | ||
1652 | bool cfgFileNameArg = false; | | |||
1653 | QList<Param> parameters; | | |||
1654 | QList<Signal> signalList; | | |||
1655 | QStringList includes; | | |||
1656 | | ||||
1657 | QList<CfgEntry *> entries; | | |||
1658 | 1205 | | |||
1659 | for (QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { | 1206 | for (QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { | ||
1660 | QString tag = e.tagName(); | 1207 | QString tag = e.tagName(); | ||
1661 | 1208 | | |||
1662 | if (tag == QLatin1String("include")) { | 1209 | if (tag == QLatin1String("include")) { | ||
1663 | QString includeFile = e.text(); | 1210 | QString includeFile = e.text(); | ||
1664 | if (!includeFile.isEmpty()) { | 1211 | if (!includeFile.isEmpty()) { | ||
1665 | includes.append(includeFile); | 1212 | parseResult.includes.append(includeFile); | ||
1666 | } | 1213 | } | ||
1667 | 1214 | | |||
1668 | } else if (tag == QLatin1String("kcfgfile")) { | 1215 | } else if (tag == QLatin1String("kcfgfile")) { | ||
dfaure: ^ | |||||
1669 | cfgFileName = e.attribute(QStringLiteral("name")); | 1216 | parseResult.cfgFileName = e.attribute(QStringLiteral("name")); | ||
1670 | cfgFileNameArg = e.attribute(QStringLiteral("arg")).toLower() == QLatin1String("true"); | 1217 | parseResult.cfgFileNameArg = e.attribute(QStringLiteral("arg")).toLower() == QLatin1String("true"); | ||
1671 | for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { | 1218 | for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { | ||
1672 | if (e2.tagName() == QLatin1String("parameter")) { | 1219 | if (e2.tagName() == QLatin1String("parameter")) { | ||
1673 | Param p; | 1220 | Param p; | ||
1674 | p.name = e2.attribute(QStringLiteral("name")); | 1221 | p.name = e2.attribute(QStringLiteral("name")); | ||
1675 | p.type = e2.attribute(QStringLiteral("type")); | 1222 | p.type = e2.attribute(QStringLiteral("type")); | ||
1676 | if (p.type.isEmpty()) { | 1223 | if (p.type.isEmpty()) { | ||
1677 | p.type = QStringLiteral("String"); | 1224 | p.type = QStringLiteral("String"); | ||
1678 | } | 1225 | } | ||
1679 | parameters.append(p); | 1226 | parseResult.parameters.append(p); | ||
1680 | } | 1227 | } | ||
1681 | } | 1228 | } | ||
1682 | 1229 | | |||
1683 | } else if (tag == QLatin1String("group")) { | 1230 | } else if (tag == QLatin1String("group")) { | ||
1684 | QString group = e.attribute(QStringLiteral("name")); | 1231 | QString group = e.attribute(QStringLiteral("name")); | ||
1685 | if (group.isEmpty()) { | 1232 | if (group.isEmpty()) { | ||
1686 | cerr << "Group without name" << endl; | 1233 | cerr << "Group without name" << endl; | ||
1687 | return 1; | 1234 | return 1; | ||
1688 | } | 1235 | } | ||
1689 | for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { | 1236 | for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { | ||
1690 | if (e2.tagName() != QLatin1String("entry")) { | 1237 | if (e2.tagName() != QLatin1String("entry")) { | ||
1691 | continue; | 1238 | continue; | ||
1692 | } | 1239 | } | ||
1693 | CfgEntry *entry = parseEntry(group, e2, cfg); | 1240 | CfgEntry *entry = parseEntry(group, e2, cfg); | ||
1694 | if (entry) { | 1241 | if (entry) { | ||
1695 | entries.append(entry); | 1242 | parseResult.entries.append(entry); | ||
1696 | } else { | 1243 | } else { | ||
1697 | cerr << "Can not parse entry." << endl; | 1244 | cerr << "Can not parse entry." << endl; | ||
1698 | return 1; | 1245 | return 1; | ||
1699 | } | 1246 | } | ||
1700 | } | 1247 | } | ||
1701 | } else if (tag == QLatin1String("signal")) { | 1248 | } else if (tag == QLatin1String("signal")) { | ||
1702 | QString signalName = e.attribute(QStringLiteral("name")); | 1249 | QString signalName = e.attribute(QStringLiteral("name")); | ||
1703 | if (signalName.isEmpty()) { | 1250 | if (signalName.isEmpty()) { | ||
Show All 12 Lines | 1261 | if (argument.type.isEmpty()) { | |||
1716 | return 1; | 1263 | return 1; | ||
1717 | } | 1264 | } | ||
1718 | argument.variableName = e2.text(); | 1265 | argument.variableName = e2.text(); | ||
1719 | theSignal.arguments.append(argument); | 1266 | theSignal.arguments.append(argument); | ||
1720 | } else if (e2.tagName() == QLatin1String("label")) { | 1267 | } else if (e2.tagName() == QLatin1String("label")) { | ||
1721 | theSignal.label = e2.text(); | 1268 | theSignal.label = e2.text(); | ||
1722 | } | 1269 | } | ||
1723 | } | 1270 | } | ||
1724 | signalList.append(theSignal); | 1271 | | ||
1272 | parseResult.signalList.append(theSignal); | ||||
1725 | } | 1273 | } | ||
1726 | } | 1274 | } | ||
1727 | 1275 | | |||
1728 | if (cfg.className.isEmpty()) { | 1276 | if (cfg.className.isEmpty()) { | ||
1729 | cerr << "Class name missing" << endl; | 1277 | cerr << "Class name missing" << endl; | ||
1730 | return 1; | 1278 | return 1; | ||
1731 | } | 1279 | } | ||
1732 | 1280 | | |||
1733 | if (cfg.singleton && !parameters.isEmpty()) { | 1281 | if (cfg.singleton && !parseResult.parameters.isEmpty()) { | ||
1734 | cerr << "Singleton class can not have parameters" << endl; | 1282 | cerr << "Singleton class can not have parameters" << endl; | ||
1735 | return 1; | 1283 | return 1; | ||
1736 | } | 1284 | } | ||
1737 | 1285 | | |||
1738 | if (!cfgFileName.isEmpty() && cfgFileNameArg) { | 1286 | if (!parseResult.cfgFileName.isEmpty() && parseResult.cfgFileNameArg) { | ||
1739 | cerr << "Having both a fixed filename and a filename as argument is not possible." << endl; | 1287 | cerr << "Having both a fixed filename and a filename as argument is not possible." << endl; | ||
1740 | return 1; | 1288 | return 1; | ||
1741 | } | 1289 | } | ||
1742 | 1290 | | |||
1743 | if (entries.isEmpty()) { | 1291 | if (parseResult.entries.isEmpty()) { | ||
1744 | cerr << "No entries." << endl; | 1292 | cerr << "No entries." << endl; | ||
1745 | } | 1293 | } | ||
1746 | 1294 | | |||
1747 | #if 0 | 1295 | QString headerFileName = cfg.baseName + '.' + cfg.headerExtension; | ||
1748 | CfgEntry *cfg; | 1296 | QString implementationFileName = cfg.baseName + '.' + cfg.sourceExtension; | ||
1749 | for (cfg = entries.first(); cfg; cfg = entries.next()) { | | |||
1750 | cfg->dump(); | | |||
1751 | } | | |||
1752 | #endif | | |||
1753 | | ||||
1754 | QString headerFileName = baseName + '.' + cfg.headerExtension; | | |||
1755 | QString implementationFileName = baseName + '.' + cfg.sourceExtension; | | |||
1756 | QString mocFileName = baseName + ".moc"; | | |||
1757 | QString cppPreamble; // code to be inserted at the beginnin of the cpp file, e.g. initialization of static values | | |||
1758 | | ||||
1759 | QFile header(baseDir + headerFileName); | | |||
1760 | if (!header.open(QIODevice::WriteOnly)) { | | |||
1761 | cerr << "Can not open '" << baseDir << headerFileName << "for writing." << endl; | | |||
1762 | return 1; | | |||
1763 | } | | |||
1764 | | ||||
1765 | QTextStream h(&header); | | |||
1766 | | ||||
1767 | h.setCodec("utf-8"); | | |||
1768 | | ||||
1769 | h << "// This file is generated by kconfig_compiler_kf5 from " << QFileInfo(inputFilename).fileName() << "." << endl; | | |||
1770 | h << "// All changes you do to this file will be lost." << endl; | | |||
1771 | | ||||
1772 | h << "#ifndef " << (!cfg.nameSpace.isEmpty() ? QString(QString(cfg.nameSpace).replace(QLatin1String("::"), QLatin1String("_")).toUpper() + '_') : QLatin1String("")) | | |||
1773 | << cfg.className.toUpper() << "_H" << endl; | | |||
1774 | h << "#define " << (!cfg.nameSpace.isEmpty() ? QString(QString(cfg.nameSpace).replace(QLatin1String("::"), QLatin1String("_")).toUpper() + '_') : QLatin1String("")) | | |||
1775 | << cfg.className.toUpper() << "_H" << endl << endl; | | |||
1776 | | ||||
1777 | // Includes | | |||
1778 | QStringList::ConstIterator it; | | |||
1779 | for (it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it) { | | |||
1780 | if ((*it).startsWith('"')) { | | |||
1781 | h << "#include " << *it << endl; | | |||
1782 | } else { | | |||
1783 | h << "#include <" << *it << ">" << endl; | | |||
1784 | } | | |||
1785 | } | | |||
1786 | | ||||
1787 | if (!cfg.headerIncludes.isEmpty()) { | | |||
1788 | h << endl; | | |||
1789 | } | | |||
1790 | | ||||
1791 | if (!cfg.singleton && parameters.isEmpty()) { | | |||
1792 | h << "#include <qglobal.h>" << endl; | | |||
1793 | } | | |||
1794 | | ||||
1795 | if (cfg.inherits == QLatin1String("KCoreConfigSkeleton")) { | | |||
1796 | h << "#include <kcoreconfigskeleton.h>" << endl; | | |||
1797 | } else { | | |||
1798 | h << "#include <kconfigskeleton.h>" << endl; | | |||
1799 | } | | |||
1800 | | ||||
1801 | h << "#include <QCoreApplication>" << endl; | | |||
1802 | h << "#include <QDebug>" << endl << endl; | | |||
1803 | | ||||
1804 | // Includes | | |||
1805 | for (it = includes.constBegin(); it != includes.constEnd(); ++it) { | | |||
1806 | if ((*it).startsWith('"')) { | | |||
1807 | h << "#include " << *it << endl; | | |||
1808 | } else { | | |||
1809 | h << "#include <" << *it << ">" << endl; | | |||
1810 | } | | |||
1811 | } | | |||
1812 | | ||||
1813 | beginNamespaces(cfg.nameSpace, h); | | |||
1814 | | ||||
1815 | // Private class declaration | | |||
1816 | if (cfg.dpointer) { | | |||
1817 | h << "class " << cfg.className << "Private;" << endl << endl; | | |||
1818 | } | | |||
1819 | | ||||
1820 | // Class declaration header | | |||
1821 | h << "class " << cfg.visibility << cfg.className << " : public " << cfg.inherits << endl; | | |||
1822 | | ||||
1823 | h << "{" << endl; | | |||
1824 | // Add Q_OBJECT macro if the config need signals. | | |||
1825 | if (!signalList.isEmpty() || cfg.generateProperties) { | | |||
1826 | h << " Q_OBJECT" << endl; | | |||
1827 | } | | |||
1828 | h << " public:" << endl; | | |||
1829 | | ||||
1830 | // enums | | |||
1831 | QList<CfgEntry *>::ConstIterator itEntry; | | |||
1832 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
1833 | const CfgEntry::Choices &choices = (*itEntry)->choices(); | | |||
1834 | const QList<CfgEntry::Choice> chlist = choices.choices; | | |||
1835 | if (!chlist.isEmpty()) { | | |||
1836 | QStringList values; | | |||
1837 | QList<CfgEntry::Choice>::ConstIterator itChoice; | | |||
1838 | for (itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice) { | | |||
1839 | values.append(choices.prefix + (*itChoice).name); | | |||
1840 | } | | |||
1841 | if (choices.name().isEmpty()) { | | |||
1842 | if (cfg.globalEnums) { | | |||
1843 | h << " enum " << enumName((*itEntry)->name(), (*itEntry)->choices()) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; | | |||
1844 | } else { | | |||
1845 | // Create an automatically named enum | | |||
1846 | h << " class " << enumName((*itEntry)->name(), (*itEntry)->choices()) << endl; | | |||
1847 | h << " {" << endl; | | |||
1848 | h << " public:" << endl; | | |||
1849 | h << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };" << endl; | | |||
1850 | h << " };" << endl; | | |||
1851 | } | | |||
1852 | } else if (!choices.external()) { | | |||
1853 | // Create a named enum | | |||
1854 | h << " enum " << enumName((*itEntry)->name(), (*itEntry)->choices()) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; | | |||
1855 | } | | |||
1856 | } | | |||
1857 | const QStringList values = (*itEntry)->paramValues(); | | |||
1858 | if (!values.isEmpty()) { | | |||
1859 | if (cfg.globalEnums) { | | |||
1860 | // ### FIXME!! | | |||
1861 | // make the following string table an index-based string search! | | |||
1862 | // ### | | |||
1863 | h << " enum " << enumName((*itEntry)->param()) << " { " << values.join(QStringLiteral(", ")) << " };" << endl; | | |||
1864 | h << " static const char* const " << enumName((*itEntry)->param()) << "ToString[];" << endl; | | |||
1865 | cppPreamble += "const char* const " + cfg.className + "::" + enumName((*itEntry)->param()) + | | |||
1866 | "ToString[] = { \"" + values.join(QStringLiteral("\", \"")) + "\" };\n"; | | |||
1867 | } else { | | |||
1868 | h << " class " << enumName((*itEntry)->param()) << endl; | | |||
1869 | h << " {" << endl; | | |||
1870 | h << " public:" << endl; | | |||
1871 | h << " enum type { " << values.join(QStringLiteral(", ")) << ", COUNT };" << endl; | | |||
1872 | h << " static const char* const enumToString[];" << endl; | | |||
1873 | h << " };" << endl; | | |||
1874 | cppPreamble += "const char* const " + cfg.className + "::" + enumName((*itEntry)->param()) + | | |||
1875 | "::enumToString[] = { \"" + values.join(QStringLiteral("\", \"")) + "\" };\n"; | | |||
1876 | } | | |||
1877 | } | | |||
1878 | } | | |||
1879 | h << endl; | | |||
1880 | | ||||
1881 | | ||||
1882 | // Constructor or singleton accessor | | |||
1883 | if (!cfg.singleton) { | | |||
1884 | h << " " << cfg.className << "("; | | |||
1885 | if (cfgFileNameArg) { | | |||
1886 | if (cfg.forceStringFilename) | | |||
1887 | h << " const QString &cfgfilename" | | |||
1888 | << (parameters.isEmpty() ? " = QString()" : ", "); | | |||
1889 | else | | |||
1890 | h << " KSharedConfig::Ptr config" | | |||
1891 | << (parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", "); | | |||
1892 | } | | |||
1893 | for (QList<Param>::ConstIterator it = parameters.constBegin(); | | |||
1894 | it != parameters.constEnd(); ++it) { | | |||
1895 | if (it != parameters.constBegin()) { | | |||
1896 | h << ","; | | |||
1897 | } | | |||
1898 | h << " " << param((*it).type) << " " << (*it).name; | | |||
1899 | } | | |||
1900 | if (cfg.parentInConstructor) { | | |||
1901 | if (cfgFileNameArg || !parameters.isEmpty()) { | | |||
1902 | h << ","; | | |||
1903 | } | | |||
1904 | h << " QObject *parent = nullptr"; | | |||
1905 | } | | |||
1906 | h << " );" << endl; | | |||
1907 | } else { | | |||
1908 | h << " static " << cfg.className << " *self();" << endl; | | |||
1909 | if (cfgFileNameArg) { | | |||
1910 | h << " static void instance(const QString& cfgfilename);" << endl; | | |||
1911 | h << " static void instance(KSharedConfig::Ptr config);" << endl; | | |||
1912 | } | | |||
1913 | } | | |||
1914 | | ||||
1915 | // Destructor | | |||
1916 | h << " ~" << cfg.className << "();" << endl << endl; | | |||
1917 | | ||||
1918 | // global variables | | |||
1919 | if (cfg.staticAccessors) { | | |||
1920 | This = QStringLiteral("self()->"); | | |||
1921 | } else { | | |||
1922 | Const = QStringLiteral(" const"); | | |||
1923 | } | | |||
1924 | | ||||
1925 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
1926 | QString n = (*itEntry)->name(); | | |||
1927 | QString t = (*itEntry)->type(); | | |||
1928 | | ||||
1929 | // Manipulator | | |||
1930 | if (cfg.allMutators || cfg.mutators.contains(n)) { | | |||
1931 | h << " /**" << endl; | | |||
1932 | h << " Set " << (*itEntry)->label() << endl; | | |||
1933 | h << " */" << endl; | | |||
1934 | if (cfg.staticAccessors) { | | |||
1935 | h << " static" << endl; | | |||
1936 | } | | |||
1937 | h << " void " << setFunction(n) << "( "; | | |||
1938 | if (!(*itEntry)->param().isEmpty()) { | | |||
1939 | h << cppType((*itEntry)->paramType()) << " i, "; | | |||
1940 | } | | |||
1941 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
1942 | h << enumType(*itEntry, cfg.globalEnums); | | |||
1943 | } else { | | |||
1944 | h << param(t); | | |||
1945 | } | | |||
1946 | h << " v )"; | | |||
1947 | // function body inline only if not using dpointer | | |||
1948 | // for BC mode | | |||
1949 | if (!cfg.dpointer) { | | |||
1950 | h << endl << " {" << endl; | | |||
1951 | h << indent(memberMutatorBody(*itEntry, cfg), 6); | | |||
1952 | h << " }" << endl; | | |||
1953 | } else { | | |||
1954 | h << ";" << endl; | | |||
1955 | } | | |||
1956 | } | | |||
1957 | h << endl; | | |||
1958 | | ||||
1959 | QString returnType; | | |||
1960 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
1961 | returnType = enumType(*itEntry, cfg.globalEnums); | | |||
1962 | } else { | | |||
1963 | returnType = cppType(t); | | |||
1964 | } | | |||
1965 | | ||||
1966 | if (cfg.generateProperties) { | | |||
1967 | h << " Q_PROPERTY(" << returnType << ' ' << getFunction(n); | | |||
1968 | h << " READ " << getFunction(n); | | |||
1969 | if (cfg.allMutators || cfg.mutators.contains(n)) { | | |||
1970 | const QString signal = changeSignalName(n); | | |||
1971 | h << " WRITE " << setFunction(n); | | |||
1972 | h << " NOTIFY " << signal; | | |||
1973 | | ||||
1974 | //If we have the modified signal, we'll also need | | |||
1975 | //the changed signal as well | | |||
1976 | Signal s; | | |||
1977 | s.name = signal; | | |||
1978 | s.modify = true; | | |||
1979 | signalList.append(s); | | |||
1980 | } else { | | |||
1981 | h << " CONSTANT"; | | |||
1982 | } | | |||
1983 | h << ")" << endl; | | |||
1984 | } | | |||
1985 | // Accessor | | |||
1986 | h << " /**" << endl; | | |||
1987 | h << " Get " << (*itEntry)->label() << endl; | | |||
1988 | h << " */" << endl; | | |||
1989 | if (cfg.staticAccessors) { | | |||
1990 | h << " static" << endl; | | |||
1991 | } | | |||
1992 | h << " "; | | |||
1993 | h << returnType; | | |||
1994 | h << " " << getFunction(n) << "("; | | |||
1995 | if (!(*itEntry)->param().isEmpty()) { | | |||
1996 | h << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
1997 | } | | |||
1998 | h << ")" << Const; | | |||
1999 | // function body inline only if not using dpointer | | |||
2000 | // for BC mode | | |||
2001 | if (!cfg.dpointer) { | | |||
2002 | h << endl << " {" << endl; | | |||
2003 | h << indent(memberAccessorBody(*itEntry, cfg.globalEnums, cfg), 6); | | |||
2004 | h << " }" << endl; | | |||
2005 | } else { | | |||
2006 | h << ";" << endl; | | |||
2007 | } | | |||
2008 | | ||||
2009 | // Default value Accessor | | |||
2010 | if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) { | | |||
2011 | h << endl; | | |||
2012 | h << " /**" << endl; | | |||
2013 | h << " Get " << (*itEntry)->label() << " default value" << endl; | | |||
2014 | h << " */" << endl; | | |||
2015 | if (cfg.staticAccessors) { | | |||
2016 | h << " static" << endl; | | |||
2017 | } | | |||
2018 | h << " "; | | |||
2019 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
2020 | h << enumType(*itEntry, cfg.globalEnums); | | |||
2021 | } else { | | |||
2022 | h << cppType(t); | | |||
2023 | } | | |||
2024 | h << " " << getDefaultFunction(n) << "("; | | |||
2025 | if (!(*itEntry)->param().isEmpty()) { | | |||
2026 | h << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2027 | } | | |||
2028 | h << ")" << Const << endl; | | |||
2029 | h << " {" << endl; | | |||
2030 | h << " return "; | | |||
2031 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
2032 | h << "static_cast<" << enumType(*itEntry, cfg.globalEnums) << ">("; | | |||
2033 | } | | |||
2034 | h << getDefaultFunction(n) << "_helper("; | | |||
2035 | if (!(*itEntry)->param().isEmpty()) { | | |||
2036 | h << " i "; | | |||
2037 | } | | |||
2038 | h << ")"; | | |||
2039 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
2040 | h << ")"; | | |||
2041 | } | | |||
2042 | h << ";" << endl; | | |||
2043 | h << " }" << endl; | | |||
2044 | } | | |||
2045 | | ||||
2046 | // Item accessor | | |||
2047 | if (cfg.itemAccessors) { | | |||
2048 | h << endl; | | |||
2049 | h << " /**" << endl; | | |||
2050 | h << " Get Item object corresponding to " << n << "()" | | |||
2051 | << endl; | | |||
2052 | h << " */" << endl; | | |||
2053 | h << " Item" << itemType((*itEntry)->type()) << " *" | | |||
2054 | << getFunction(n) << "Item("; | | |||
2055 | if (!(*itEntry)->param().isEmpty()) { | | |||
2056 | h << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2057 | } | | |||
2058 | h << ")"; | | |||
2059 | if (!cfg.dpointer) { | | |||
2060 | h << endl << " {" << endl; | | |||
2061 | h << indent(itemAccessorBody((*itEntry), cfg), 6); | | |||
2062 | h << " }" << endl; | | |||
2063 | } else { | | |||
2064 | h << ";" << endl; | | |||
2065 | } | | |||
2066 | } | | |||
2067 | | ||||
2068 | h << endl; | | |||
2069 | } | | |||
2070 | | ||||
2071 | // Signal definition. | | |||
2072 | const bool hasSignals = !signalList.isEmpty(); | | |||
2073 | bool hasNonModifySignals = false; | | |||
2074 | if (hasSignals) { | | |||
2075 | h << "\n enum {" << endl; | | |||
2076 | unsigned val = 1; | | |||
2077 | QList<Signal>::ConstIterator it, itEnd = signalList.constEnd(); | | |||
2078 | for (it = signalList.constBegin(); it != itEnd; val <<= 1) { | | |||
2079 | hasNonModifySignals |= !it->modify; | | |||
2080 | if (!val) { | | |||
2081 | cerr << "Too many signals to create unique bit masks" << endl; | | |||
2082 | exit(1); | | |||
2083 | } | | |||
2084 | Signal signal = *it; | | |||
2085 | h << " " << signalEnumName(signal.name) << " = 0x" << hex << val; | | |||
2086 | if (++it != itEnd) { | | |||
2087 | h << ","; | | |||
2088 | } | | |||
2089 | h << endl; | | |||
2090 | } | | |||
2091 | h << " };" << dec << endl << endl; | | |||
2092 | | ||||
2093 | h << " Q_SIGNALS:"; | | |||
2094 | for (const Signal &signal : qAsConst(signalList)) { | | |||
2095 | h << endl; | | |||
2096 | if (!signal.label.isEmpty()) { | | |||
2097 | h << " /**" << endl; | | |||
2098 | h << " " << signal.label << endl; | | |||
2099 | h << " */" << endl; | | |||
2100 | } | | |||
2101 | h << " void " << signal.name << "("; | | |||
2102 | QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); | | |||
2103 | for (it = signal.arguments.constBegin(); it != itEnd;) { | | |||
2104 | SignalArguments argument = *it; | | |||
2105 | QString type = param(argument.type); | | |||
2106 | if (cfg.useEnumTypes && argument.type == QLatin1String("Enum")) { | | |||
2107 | for (int i = 0, end = entries.count(); i < end; ++i) { | | |||
2108 | if (entries[i]->name() == argument.variableName) { | | |||
2109 | type = enumType(entries[i], cfg.globalEnums); | | |||
2110 | break; | | |||
2111 | } | | |||
2112 | } | | |||
2113 | } | | |||
2114 | h << type << " " << argument.variableName; | | |||
2115 | if (++it != itEnd) { | | |||
2116 | h << ", "; | | |||
2117 | } | | |||
2118 | } | | |||
2119 | h << ");" << endl; | | |||
2120 | } | | |||
2121 | h << endl; | | |||
2122 | | ||||
2123 | h << " private:" << endl; | | |||
2124 | h << " void itemChanged(quint64 flags);" << endl; | | |||
2125 | h << endl; | | |||
2126 | } | | |||
2127 | | ||||
2128 | h << " protected:" << endl; | | |||
2129 | | ||||
2130 | // Private constructor for singleton | | |||
2131 | if (cfg.singleton) { | | |||
2132 | h << " " << cfg.className << "("; | | |||
2133 | if (cfgFileNameArg) { | | |||
2134 | h << "KSharedConfig::Ptr config"; | | |||
2135 | } | | |||
2136 | if (cfg.parentInConstructor) { | | |||
2137 | if (cfgFileNameArg) { | | |||
2138 | h << ", "; | | |||
2139 | } | | |||
2140 | h << "QObject *parent = nullptr"; | | |||
2141 | } | | |||
2142 | h << ");" << endl; | | |||
2143 | h << " friend class " << cfg.className << "Helper;" << endl << endl; | | |||
2144 | } | | |||
2145 | | ||||
2146 | if (hasNonModifySignals) { | | |||
2147 | h << " bool usrSave() override;" << endl; | | |||
2148 | } | | |||
2149 | | ||||
2150 | // Member variables | | |||
2151 | if (!cfg.memberVariables.isEmpty() && cfg.memberVariables != QLatin1String("private") && cfg.memberVariables != QLatin1String("dpointer")) { | | |||
2152 | h << " " << cfg.memberVariables << ":" << endl; | | |||
2153 | } | | |||
2154 | | ||||
2155 | // Class Parameters | | |||
2156 | for (QList<Param>::ConstIterator it = parameters.constBegin(); | | |||
2157 | it != parameters.constEnd(); ++it) { | | |||
2158 | h << " " << cppType((*it).type) << " mParam" << (*it).name << ";" << endl; | | |||
2159 | } | | |||
2160 | | ||||
2161 | if (cfg.memberVariables != QLatin1String("dpointer")) { | | |||
2162 | QString group; | | |||
2163 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2164 | if ((*itEntry)->group() != group) { | | |||
2165 | group = (*itEntry)->group(); | | |||
2166 | h << endl; | | |||
2167 | h << " // " << group << endl; | | |||
2168 | } | | |||
2169 | h << " " << cppType((*itEntry)->type()) << " " << varName((*itEntry)->name(), cfg); | | |||
2170 | if (!(*itEntry)->param().isEmpty()) { | | |||
2171 | h << QStringLiteral("[%1]").arg((*itEntry)->paramMax() + 1); | | |||
2172 | } | | |||
2173 | h << ";" << endl; | | |||
2174 | | ||||
2175 | if (cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name())) { | | |||
2176 | h << " "; | | |||
2177 | if (cfg.staticAccessors) { | | |||
2178 | h << "static "; | | |||
2179 | } | | |||
2180 | h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; | | |||
2181 | if (!(*itEntry)->param().isEmpty()) { | | |||
2182 | h << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2183 | } | | |||
2184 | h << ")" << Const << ";" << endl; | | |||
2185 | } | | |||
2186 | } | | |||
2187 | | ||||
2188 | h << endl << " private:" << endl; | | |||
2189 | if (cfg.itemAccessors) { | | |||
2190 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2191 | h << " Item" << itemType((*itEntry)->type()) << " *" << itemVar(*itEntry, cfg); | | |||
2192 | if (!(*itEntry)->param().isEmpty()) { | | |||
2193 | h << QStringLiteral("[%1]").arg((*itEntry)->paramMax() + 1); | | |||
2194 | } | | |||
2195 | h << ";" << endl; | | |||
2196 | } | | |||
2197 | } | | |||
2198 | if (hasNonModifySignals) { | | |||
2199 | h << " uint " << varName(QStringLiteral("settingsChanged"), cfg) << ";" << endl; | | |||
2200 | } | | |||
2201 | | ||||
2202 | } else { | | |||
2203 | // use a private class for both member variables and items | | |||
2204 | h << " private:" << endl; | | |||
2205 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2206 | if (cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name())) { | | |||
2207 | h << " "; | | |||
2208 | if (cfg.staticAccessors) { | | |||
2209 | h << "static "; | | |||
2210 | } | | |||
2211 | h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; | | |||
2212 | if (!(*itEntry)->param().isEmpty()) { | | |||
2213 | h << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2214 | } | | |||
2215 | h << ")" << Const << ";" << endl; | | |||
2216 | } | | |||
2217 | } | | |||
2218 | h << " " + cfg.className + "Private *d;" << endl; | | |||
2219 | } | | |||
2220 | | ||||
2221 | if (cfg.customAddons) { | | |||
2222 | h << " // Include custom additions" << endl; | | |||
2223 | h << " #include \"" << filenameOnly(baseName) << "_addons." << cfg.headerExtension << '"' << endl; | | |||
2224 | } | | |||
2225 | | ||||
2226 | h << "};" << endl << endl; | | |||
2227 | | ||||
2228 | endNamespaces(cfg.nameSpace, h); | | |||
2229 | | ||||
2230 | h << "#endif" << endl << endl; | | |||
2231 | | ||||
2232 | header.close(); | | |||
2233 | | ||||
2234 | QFile implementation(baseDir + implementationFileName); | | |||
2235 | if (!implementation.open(QIODevice::WriteOnly)) { | | |||
2236 | cerr << "Can not open '" << implementationFileName << "for writing." | | |||
2237 | << endl; | | |||
2238 | return 1; | | |||
2239 | } | | |||
2240 | | ||||
2241 | QTextStream cpp(&implementation); | | |||
2242 | | ||||
2243 | cpp.setCodec("utf-8"); | | |||
2244 | | ||||
2245 | cpp << "// This file is generated by kconfig_compiler_kf5 from " << QFileInfo(inputFilename).fileName() << "." << endl; | | |||
2246 | cpp << "// All changes you do to this file will be lost." << endl << endl; | | |||
2247 | | ||||
2248 | cpp << "#include \"" << headerFileName << "\"" << endl << endl; | | |||
2249 | | ||||
2250 | for (it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it) { | | |||
2251 | if ((*it).startsWith('"')) { | | |||
2252 | cpp << "#include " << *it << endl; | | |||
2253 | } else { | | |||
2254 | cpp << "#include <" << *it << ">" << endl; | | |||
2255 | } | | |||
2256 | } | | |||
2257 | | ||||
2258 | if (!cfg.sourceIncludes.isEmpty()) { | | |||
2259 | cpp << endl; | | |||
2260 | } | | |||
2261 | | ||||
2262 | if (cfg.setUserTexts && cfg.translationSystem == CfgConfig::KdeTranslation) { | | |||
2263 | cpp << "#include <klocalizedstring.h>" << endl << endl; | | |||
2264 | } | | |||
2265 | | ||||
2266 | // Header required by singleton implementation | | |||
2267 | if (cfg.singleton) { | | |||
2268 | cpp << "#include <qglobal.h>" << endl << "#include <QFile>" << endl << endl; | | |||
2269 | } | | |||
2270 | if (cfg.singleton && cfgFileNameArg) { | | |||
2271 | cpp << "#include <QDebug>" << endl << endl; | | |||
2272 | } | | |||
2273 | | ||||
2274 | if (!cfg.nameSpace.isEmpty()) { | | |||
2275 | cpp << "using namespace " << cfg.nameSpace << ";" << endl << endl; | | |||
2276 | } | | |||
2277 | | ||||
2278 | QString group; | | |||
2279 | | ||||
2280 | // private class implementation | | |||
2281 | if (cfg.dpointer) { | | |||
2282 | beginNamespaces(cfg.nameSpace, cpp); | | |||
2283 | cpp << "class " << cfg.className << "Private" << endl; | | |||
2284 | cpp << "{" << endl; | | |||
2285 | cpp << " public:" << endl; | | |||
2286 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2287 | if ((*itEntry)->group() != group) { | | |||
2288 | group = (*itEntry)->group(); | | |||
2289 | cpp << endl; | | |||
2290 | cpp << " // " << group << endl; | | |||
2291 | } | | |||
2292 | cpp << " " << cppType((*itEntry)->type()) << " " << varName((*itEntry)->name(), cfg); | | |||
2293 | if (!(*itEntry)->param().isEmpty()) { | | |||
2294 | cpp << QStringLiteral("[%1]").arg((*itEntry)->paramMax() + 1); | | |||
2295 | } | | |||
2296 | cpp << ";" << endl; | | |||
2297 | } | | |||
2298 | cpp << endl << " // items" << endl; | | |||
2299 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2300 | const QString declType = (*itEntry)->signalList().isEmpty() | | |||
2301 | ? QString(cfg.inherits + "::Item" + itemType((*itEntry)->type())) | | |||
2302 | : QStringLiteral("KConfigCompilerSignallingItem"); | | |||
2303 | cpp << " " << declType << " *" << itemVar( *itEntry, cfg ); | | |||
2304 | if (!(*itEntry)->param().isEmpty()) { | | |||
2305 | cpp << QStringLiteral("[%1]").arg((*itEntry)->paramMax() + 1); | | |||
2306 | } | | |||
2307 | cpp << ";" << endl; | | |||
2308 | } | | |||
2309 | if (hasNonModifySignals) { | | |||
2310 | cpp << " uint " << varName(QStringLiteral("settingsChanged"), cfg) << ";" << endl; | | |||
2311 | } | | |||
2312 | | ||||
2313 | cpp << "};" << endl << endl; | | |||
2314 | endNamespaces(cfg.nameSpace, cpp); | | |||
2315 | } | | |||
2316 | | ||||
2317 | // Singleton implementation | | |||
2318 | if (cfg.singleton) { | | |||
2319 | beginNamespaces(cfg.nameSpace, cpp); | | |||
2320 | cpp << "class " << cfg.className << "Helper" << endl; | | |||
2321 | cpp << '{' << endl; | | |||
2322 | cpp << " public:" << endl; | | |||
2323 | cpp << " " << cfg.className << "Helper() : q(nullptr) {}" << endl; | | |||
2324 | cpp << " ~" << cfg.className << "Helper() { delete q; }" << endl; | | |||
2325 | cpp << " " << cfg.className << "Helper(const " << cfg.className << "Helper&) = delete;" << endl; | | |||
2326 | cpp << " " << cfg.className << "Helper& operator=(const " << cfg.className << "Helper&) = delete;" << endl; | | |||
2327 | cpp << " " << cfg.className << " *q;" << endl; | | |||
2328 | cpp << "};" << endl; | | |||
2329 | endNamespaces(cfg.nameSpace, cpp); | | |||
2330 | cpp << "Q_GLOBAL_STATIC(" << cfg.className << "Helper, s_global" << cfg.className << ")" << endl; | | |||
2331 | | ||||
2332 | cpp << cfg.className << " *" << cfg.className << "::self()" << endl; | | |||
2333 | cpp << "{" << endl; | | |||
2334 | if (cfgFileNameArg) { | | |||
2335 | cpp << " if (!s_global" << cfg.className << "()->q)" << endl; | | |||
2336 | cpp << " qFatal(\"you need to call " << cfg.className << "::instance before using\");" << endl; | | |||
2337 | } else { | | |||
2338 | cpp << " if (!s_global" << cfg.className << "()->q) {" << endl; | | |||
2339 | cpp << " new " << cfg.className << ';' << endl; | | |||
2340 | cpp << " s_global" << cfg.className << "()->q->read();" << endl; | | |||
2341 | cpp << " }" << endl << endl; | | |||
2342 | } | | |||
2343 | cpp << " return s_global" << cfg.className << "()->q;" << endl; | | |||
2344 | cpp << "}" << endl << endl; | | |||
2345 | | ||||
2346 | if (cfgFileNameArg) { | | |||
2347 | auto instance = [&cfg, &cpp] (const QString &type, const QString &arg, bool isString) { | | |||
2348 | cpp << "void " << cfg.className << "::instance(" << type << " " << arg << ")" << endl; | | |||
2349 | cpp << "{" << endl; | | |||
2350 | cpp << " if (s_global" << cfg.className << "()->q) {" << endl; | | |||
2351 | cpp << " qDebug() << \"" << cfg.className << "::instance called after the first use - ignoring\";" << endl; | | |||
2352 | cpp << " return;" << endl; | | |||
2353 | cpp << " }" << endl; | | |||
2354 | cpp << " new " << cfg.className << "("; | | |||
2355 | if (isString) { | | |||
2356 | cpp << "KSharedConfig::openConfig(" << arg << ")"; | | |||
2357 | } else { | | |||
2358 | cpp << "std::move(" << arg << ")"; | | |||
2359 | } | | |||
2360 | cpp << ");" << endl; | | |||
2361 | cpp << " s_global" << cfg.className << "()->q->read();" << endl; | | |||
2362 | cpp << "}" << endl << endl; | | |||
2363 | }; | | |||
2364 | instance(QStringLiteral("const QString&"), QStringLiteral("cfgfilename"), true); | | |||
2365 | instance(QStringLiteral("KSharedConfig::Ptr"), QStringLiteral("config"), false); | | |||
2366 | } | | |||
2367 | } | | |||
2368 | | ||||
2369 | if (!cppPreamble.isEmpty()) { | | |||
2370 | cpp << cppPreamble << endl; | | |||
2371 | } | | |||
2372 | | ||||
2373 | // Constructor | | |||
2374 | cpp << cfg.className << "::" << cfg.className << "("; | | |||
2375 | if (cfgFileNameArg) { | | |||
2376 | if (! cfg.forceStringFilename) { | | |||
2377 | cpp << " KSharedConfig::Ptr config"; | | |||
2378 | } else { | | |||
2379 | cpp << " const QString& config"; | | |||
2380 | } | | |||
2381 | cpp << (parameters.isEmpty() ? "" : ","); | | |||
2382 | } | | |||
2383 | | ||||
2384 | for (QList<Param>::ConstIterator it = parameters.constBegin(); | | |||
2385 | it != parameters.constEnd(); ++it) { | | |||
2386 | if (it != parameters.constBegin()) { | | |||
2387 | cpp << ","; | | |||
2388 | } | | |||
2389 | cpp << " " << param((*it).type) << " " << (*it).name; | | |||
2390 | } | | |||
2391 | | ||||
2392 | if (cfg.parentInConstructor) { | | |||
2393 | if (cfgFileNameArg || !parameters.isEmpty()) { | | |||
2394 | cpp << ","; | | |||
2395 | } | | |||
2396 | cpp << " QObject *parent"; | | |||
2397 | } | | |||
2398 | cpp << " )" << endl; | | |||
2399 | | ||||
2400 | cpp << " : " << cfg.inherits << "("; | | |||
2401 | if (!cfgFileName.isEmpty()) { | | |||
2402 | cpp << " QStringLiteral( \"" << cfgFileName << "\" "; | | |||
2403 | } | | |||
2404 | if (cfgFileNameArg) { | | |||
2405 | if (! cfg.forceStringFilename) { | | |||
2406 | cpp << " std::move( config ) "; | | |||
2407 | } else { | | |||
2408 | cpp << " config "; | | |||
2409 | } | | |||
2410 | } | | |||
2411 | if (!cfgFileName.isEmpty()) { | | |||
2412 | cpp << ") "; | | |||
2413 | } | | |||
2414 | cpp << ")" << endl; | | |||
2415 | | ||||
2416 | // Store parameters | | |||
2417 | for (QList<Param>::ConstIterator it = parameters.constBegin(); | | |||
2418 | it != parameters.constEnd(); ++it) { | | |||
2419 | cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl; | | |||
2420 | } | | |||
2421 | | ||||
2422 | if (hasNonModifySignals && !cfg.dpointer) { | | |||
2423 | cpp << " , " << varName(QStringLiteral("settingsChanged"), cfg) << "(0)" << endl; | | |||
2424 | } | | |||
2425 | | ||||
2426 | cpp << "{" << endl; | | |||
2427 | | ||||
2428 | if (cfg.parentInConstructor) { | | |||
2429 | cpp << " setParent(parent);" << endl; | | |||
2430 | } | | |||
2431 | | ||||
2432 | if (cfg.dpointer) { | | |||
2433 | cpp << " d = new " + cfg.className + "Private;" << endl; | | |||
2434 | if (hasNonModifySignals) { | | |||
2435 | cpp << " " << varPath(QStringLiteral("settingsChanged"), cfg) << " = 0;" << endl; | | |||
2436 | } | | |||
2437 | } | | |||
2438 | // Needed in case the singleton class is used as baseclass for | | |||
2439 | // another singleton. | | |||
2440 | if (cfg.singleton) { | | |||
2441 | cpp << " Q_ASSERT(!s_global" << cfg.className << "()->q);" << endl; | | |||
2442 | cpp << " s_global" << cfg.className << "()->q = this;" << endl; | | |||
2443 | } | | |||
2444 | | ||||
2445 | group.clear(); | | |||
2446 | | ||||
2447 | if (hasSignals) { | | |||
2448 | // this cast to base-class pointer-to-member is valid C++ | | |||
2449 | // https://stackoverflow.com/questions/4272909/is-it-safe-to-upcast-a-method-pointer-and-use-it-with-base-class-pointer/ | | |||
2450 | cpp << " KConfigCompilerSignallingItem::NotifyFunction notifyFunction =" | | |||
2451 | << " static_cast<KConfigCompilerSignallingItem::NotifyFunction>(&" | | |||
2452 | << cfg.className << "::itemChanged);" << endl << endl; | | |||
2453 | } | | |||
2454 | | ||||
2455 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2456 | if ((*itEntry)->group() != group) { | | |||
2457 | if (!group.isEmpty()) { | | |||
2458 | cpp << endl; | | |||
2459 | } | | |||
2460 | group = (*itEntry)->group(); | | |||
2461 | cpp << " setCurrentGroup( " << paramString(group, parameters) << " );" << endl << endl; | | |||
2462 | } | | |||
2463 | | ||||
2464 | QString key = paramString((*itEntry)->key(), parameters); | | |||
2465 | if (!(*itEntry)->code().isEmpty()) { | | |||
2466 | cpp << (*itEntry)->code() << endl; | | |||
2467 | } | | |||
2468 | if ((*itEntry)->type() == QLatin1String("Enum")) { | | |||
2469 | cpp << " QList<" + cfg.inherits + "::ItemEnum::Choice> values" | | |||
2470 | << (*itEntry)->name() << ";" << endl; | | |||
2471 | const QList<CfgEntry::Choice> choices = (*itEntry)->choices().choices; | | |||
2472 | QList<CfgEntry::Choice>::ConstIterator it; | | |||
2473 | for (it = choices.constBegin(); it != choices.constEnd(); ++it) { | | |||
2474 | cpp << " {" << endl; | | |||
2475 | cpp << " " + cfg.inherits + "::ItemEnum::Choice choice;" << endl; | | |||
2476 | cpp << " choice.name = QStringLiteral(\"" << (*it).name << "\");" << endl; | | |||
2477 | if (cfg.setUserTexts) { | | |||
2478 | if (!(*it).label.isEmpty()) { | | |||
2479 | cpp << " choice.label = " | | |||
2480 | << translatedString(cfg, (*it).label, (*it).context) | | |||
2481 | << ";" << endl; | | |||
2482 | } | | |||
2483 | if (!(*it).toolTip.isEmpty()) { | | |||
2484 | cpp << " choice.toolTip = " | | |||
2485 | << translatedString(cfg, (*it).toolTip, (*it).context) | | |||
2486 | << ";" << endl; | | |||
2487 | } | | |||
2488 | if (!(*it).whatsThis.isEmpty()) { | | |||
2489 | cpp << " choice.whatsThis = " | | |||
2490 | << translatedString(cfg, (*it).whatsThis, (*it).context) | | |||
2491 | << ";" << endl; | | |||
2492 | } | | |||
2493 | } | | |||
2494 | cpp << " values" << (*itEntry)->name() << ".append( choice );" << endl; | | |||
2495 | cpp << " }" << endl; | | |||
2496 | } | | |||
2497 | } | | |||
2498 | | ||||
2499 | if (!cfg.dpointer) { | | |||
2500 | cpp << itemDeclaration(*itEntry, cfg); | | |||
2501 | } | | |||
2502 | | ||||
2503 | if ((*itEntry)->param().isEmpty()) { | | |||
2504 | // Normal case | | |||
2505 | cpp << " " << itemPath(*itEntry, cfg) << " = " | | |||
2506 | << newItem((*itEntry), key, (*itEntry)->defaultValue(), cfg) << endl; | | |||
2507 | | ||||
2508 | if (!(*itEntry)->minValue().isEmpty()) { | | |||
2509 | cpp << " " << itemPath(*itEntry, cfg) << "->setMinValue(" << (*itEntry)->minValue() << ");" << endl; | | |||
2510 | } | | |||
2511 | if (!(*itEntry)->maxValue().isEmpty()) { | | |||
2512 | cpp << " " << itemPath(*itEntry, cfg) << "->setMaxValue(" << (*itEntry)->maxValue() << ");" << endl; | | |||
2513 | } | | |||
2514 | | ||||
2515 | if (cfg.setUserTexts) { | | |||
2516 | cpp << userTextsFunctions((*itEntry), cfg); | | |||
2517 | } | | |||
2518 | | ||||
2519 | if (cfg.allNotifiers || cfg.notifiers.contains((*itEntry)->name())) { | | |||
2520 | cpp << " " << itemPath(*itEntry, cfg) << "->setWriteFlags(KConfigBase::Notify);" << endl; | | |||
2521 | } | | |||
2522 | | ||||
2523 | cpp << " addItem( " << itemPath(*itEntry, cfg); | | |||
2524 | QString quotedName = (*itEntry)->name(); | | |||
2525 | addQuotes(quotedName); | | |||
2526 | if (quotedName != key) { | | |||
2527 | cpp << ", QStringLiteral( \"" << (*itEntry)->name() << "\" )"; | | |||
2528 | } | | |||
2529 | cpp << " );" << endl; | | |||
2530 | } else { | | |||
2531 | // Indexed | | |||
2532 | for (int i = 0; i <= (*itEntry)->paramMax(); i++) { | | |||
2533 | QString defaultStr; | | |||
2534 | QString itemVarStr(itemPath(*itEntry, cfg) + QStringLiteral("[%1]").arg(i)); | | |||
2535 | | ||||
2536 | if (!(*itEntry)->paramDefaultValue(i).isEmpty()) { | | |||
2537 | defaultStr = (*itEntry)->paramDefaultValue(i); | | |||
2538 | } else if (!(*itEntry)->defaultValue().isEmpty()) { | | |||
2539 | defaultStr = paramString((*itEntry)->defaultValue(), (*itEntry), i); | | |||
2540 | } else { | | |||
2541 | defaultStr = defaultValue((*itEntry)->type()); | | |||
2542 | } | | |||
2543 | | ||||
2544 | cpp << " " << itemVarStr << " = " | | |||
2545 | << newItem((*itEntry), paramString(key, *itEntry, i), defaultStr, cfg, QStringLiteral("[%1]").arg(i)) << endl; | | |||
2546 | | ||||
2547 | if (cfg.setUserTexts) { | | |||
2548 | cpp << userTextsFunctions(*itEntry, cfg, itemVarStr, (*itEntry)->paramName()); | | |||
2549 | } | | |||
2550 | | ||||
2551 | // Make mutators for enum parameters work by adding them with $(..) replaced by the | | |||
2552 | // param name. The check for isImmutable in the set* functions doesn't have the param | | |||
2553 | // name available, just the corresponding enum value (int), so we need to store the | | |||
2554 | // param names in a separate static list!. | | |||
2555 | cpp << " addItem( " << itemVarStr << ", QStringLiteral( \""; | | |||
2556 | if ((*itEntry)->paramType() == QLatin1String("Enum")) { | | |||
2557 | cpp << (*itEntry)->paramName().replace("$(" + (*itEntry)->param() + ')', QLatin1String("%1")).arg((*itEntry)->paramValues()[i]); | | |||
2558 | } else { | | |||
2559 | cpp << (*itEntry)->paramName().replace("$(" + (*itEntry)->param() + ')', QLatin1String("%1")).arg(i); | | |||
2560 | } | | |||
2561 | cpp << "\" ) );" << endl; | | |||
2562 | } | | |||
2563 | } | | |||
2564 | } | | |||
2565 | | ||||
2566 | cpp << "}" << endl << endl; | | |||
2567 | | ||||
2568 | if (cfg.dpointer) { | | |||
2569 | // setters and getters go in Cpp if in dpointer mode | | |||
2570 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | | |||
2571 | QString n = (*itEntry)->name(); | | |||
2572 | QString t = (*itEntry)->type(); | | |||
2573 | | ||||
2574 | // Manipulator | | |||
2575 | if (cfg.allMutators || cfg.mutators.contains(n)) { | | |||
2576 | cpp << "void " << setFunction(n, cfg.className) << "( "; | | |||
2577 | if (!(*itEntry)->param().isEmpty()) { | | |||
2578 | cpp << cppType((*itEntry)->paramType()) << " i, "; | | |||
2579 | } | | |||
2580 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
2581 | cpp << enumType(*itEntry, cfg.globalEnums); | | |||
2582 | } else { | | |||
2583 | cpp << param(t); | | |||
2584 | } | | |||
2585 | cpp << " v )" << endl; | | |||
2586 | // function body inline only if not using dpointer | | |||
2587 | // for BC mode | | |||
2588 | cpp << "{" << endl; | | |||
2589 | cpp << indent(memberMutatorBody(*itEntry, cfg), 6); | | |||
2590 | cpp << "}" << endl << endl; | | |||
2591 | } | | |||
2592 | | ||||
2593 | // Accessor | | |||
2594 | if (cfg.useEnumTypes && t == QLatin1String("Enum")) { | | |||
2595 | cpp << enumType(*itEntry, cfg.globalEnums); | | |||
2596 | } else { | | |||
2597 | cpp << cppType(t); | | |||
2598 | } | | |||
2599 | cpp << " " << getFunction(n, cfg.className) << "("; | | |||
2600 | if (!(*itEntry)->param().isEmpty()) { | | |||
2601 | cpp << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2602 | } | | |||
2603 | cpp << ")" << Const << endl; | | |||
2604 | // function body inline only if not using dpointer | | |||
2605 | // for BC mode | | |||
2606 | cpp << "{" << endl; | | |||
2607 | cpp << indent(memberAccessorBody(*itEntry, cfg.globalEnums, cfg), 2); | | |||
2608 | cpp << "}" << endl << endl; | | |||
2609 | | ||||
2610 | // Default value Accessor -- written by the loop below | | |||
2611 | | ||||
2612 | // Item accessor | | |||
2613 | if (cfg.itemAccessors) { | | |||
2614 | cpp << endl; | | |||
2615 | cpp << cfg.inherits + "::Item" << itemType((*itEntry)->type()) << " *" | | |||
2616 | << getFunction(n, cfg.className) << "Item("; | | |||
2617 | if (!(*itEntry)->param().isEmpty()) { | | |||
2618 | cpp << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2619 | } | | |||
2620 | cpp << ")" << endl; | | |||
2621 | cpp << "{" << endl; | | |||
2622 | cpp << indent(itemAccessorBody(*itEntry, cfg), 2); | | |||
2623 | cpp << "}" << endl; | | |||
2624 | } | | |||
2625 | | ||||
2626 | cpp << endl; | | |||
2627 | } | | |||
2628 | } | | |||
2629 | 1297 | | |||
2630 | // default value getters always go in Cpp | 1298 | // TODO: Move this to somewhere saner. | ||
2631 | for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { | 1299 | for (const auto &signal : qAsConst(parseResult.signalList)) { | ||
2632 | QString n = (*itEntry)->name(); | 1300 | parseResult.hasNonModifySignals |= !signal.modify; | ||
2633 | QString t = (*itEntry)->type(); | | |||
2634 | | ||||
2635 | // Default value Accessor, as "helper" function | | |||
2636 | if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) { | | |||
2637 | cpp << cppType(t) << " " << getDefaultFunction(n, cfg.className) << "_helper("; | | |||
2638 | if (!(*itEntry)->param().isEmpty()) { | | |||
2639 | cpp << " " << cppType((*itEntry)->paramType()) << " i "; | | |||
2640 | } | | |||
2641 | cpp << ")" << Const << endl; | | |||
2642 | cpp << "{" << endl; | | |||
2643 | cpp << memberGetDefaultBody(*itEntry) << endl; | | |||
2644 | cpp << "}" << endl << endl; | | |||
2645 | } | | |||
2646 | } | 1301 | } | ||
2647 | 1302 | | |||
2648 | // Destructor | 1303 | KConfigHeaderGenerator headerGenerator(inputFilename, baseDir, headerFileName, cfg, parseResult); | ||
2649 | cpp << cfg.className << "::~" << cfg.className << "()" << endl; | 1304 | headerGenerator.start(); | ||
2650 | cpp << "{" << endl; | | |||
2651 | if (cfg.dpointer) { | | |||
2652 | cpp << " delete d;" << endl; | | |||
2653 | } | | |||
2654 | if (cfg.singleton) { | | |||
2655 | cpp << " s_global" << cfg.className << "()->q = nullptr;" << endl; | | |||
2656 | } | | |||
2657 | cpp << "}" << endl << endl; | | |||
2658 | | ||||
2659 | if (hasNonModifySignals) { | | |||
2660 | cpp << "bool " << cfg.className << "::" << "usrSave()" << endl; | | |||
2661 | cpp << "{" << endl; | | |||
2662 | cpp << " const bool res = " << cfg.inherits << "::usrSave();" << endl; | | |||
2663 | cpp << " if (!res) return false;" << endl << endl; | | |||
2664 | for (const Signal &signal : qAsConst(signalList)) { | | |||
2665 | if (signal.modify) { | | |||
2666 | continue; | | |||
2667 | } | | |||
2668 | | ||||
2669 | cpp << " if ( " << varPath(QStringLiteral("settingsChanged"), cfg) << " & " << signalEnumName(signal.name) << " )" << endl; | | |||
2670 | cpp << " Q_EMIT " << signal.name << "("; | | |||
2671 | QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); | | |||
2672 | for (it = signal.arguments.constBegin(); it != itEnd;) { | | |||
2673 | SignalArguments argument = *it; | | |||
2674 | bool cast = false; | | |||
2675 | if (cfg.useEnumTypes && argument.type == QLatin1String("Enum")) { | | |||
2676 | for (int i = 0, end = entries.count(); i < end; ++i) { | | |||
2677 | if (entries[i]->name() == argument.variableName) { | | |||
2678 | cpp << "static_cast<" << enumType(entries[i], cfg.globalEnums) << ">("; | | |||
2679 | cast = true; | | |||
2680 | break; | | |||
2681 | } | | |||
2682 | } | | |||
2683 | } | | |||
2684 | cpp << varPath(argument.variableName, cfg); | | |||
2685 | if (cast) { | | |||
2686 | cpp << ")"; | | |||
2687 | } | | |||
2688 | if (++it != itEnd) { | | |||
2689 | cpp << ", "; | | |||
2690 | } | | |||
2691 | } | | |||
2692 | cpp << ");" << endl; | | |||
2693 | } | | |||
2694 | | ||||
2695 | cpp << " " << varPath(QStringLiteral("settingsChanged"), cfg) << " = 0;" << endl; | | |||
2696 | cpp << " return true;" << endl; | | |||
2697 | cpp << "}" << endl; | | |||
2698 | } | | |||
2699 | | ||||
2700 | if (hasSignals) { | | |||
2701 | cpp << endl; | | |||
2702 | cpp << "void " << cfg.className << "::" << "itemChanged(quint64 flags) {" << endl; | | |||
2703 | if (hasNonModifySignals) | | |||
2704 | cpp << " " << varPath(QStringLiteral("settingsChanged"), cfg) << " |= flags;" << endl; | | |||
2705 | | ||||
2706 | if (!signalList.isEmpty()) | | |||
2707 | cpp << endl; | | |||
2708 | | ||||
2709 | for (const Signal &signal : qAsConst(signalList)) { | | |||
2710 | if (signal.modify) { | | |||
2711 | cpp << " if ( flags & " << signalEnumName(signal.name) << " ) {" << endl; | | |||
2712 | cpp << " Q_EMIT " << signal.name << "();" << endl; | | |||
2713 | cpp << " }" << endl; | | |||
2714 | } | | |||
2715 | } | | |||
2716 | | ||||
2717 | cpp << "}" << endl; | | |||
2718 | } | | |||
2719 | | ||||
2720 | if (hasSignals || cfg.generateProperties) { | | |||
2721 | // Add includemoc if they are signals defined. | | |||
2722 | cpp << endl; | | |||
2723 | cpp << "#include \"" << mocFileName << "\"" << endl; | | |||
2724 | cpp << endl; | | |||
2725 | } | | |||
2726 | 1305 | | |||
2727 | // clear entries list | 1306 | KConfigSourceGenerator sourceGenerator(inputFilename, baseDir, headerFileName, cfg, parseResult); | ||
2728 | qDeleteAll(entries); | 1307 | sourceGenerator.start(); | ||
2729 | 1308 | | |||
2730 | implementation.close(); | 1309 | qDeleteAll(parseResult.entries); | ||
2731 | } | 1310 | } |
Space before & not after