• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • tdeconfig_compiler
tdeconfig_compiler.cpp
1/*
2 This file is part of KDE.
3
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
6 Copyright (c) 2003 Zack Rusin <zack@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22*/
23
24#include <tqfile.h>
25#include <tqtextstream.h>
26#include <tqdom.h>
27#include <tqregexp.h>
28
29#include <tdeaboutdata.h>
30#include <tdeapplication.h>
31#include <kdebug.h>
32#include <tdelocale.h>
33#include <tdecmdlineargs.h>
34#include <tdeglobal.h>
35#include <tdeconfig.h>
36#include <ksimpleconfig.h>
37#include <tdestandarddirs.h>
38
39#include <iostream>
40
41static const TDECmdLineOptions options[] =
42{
43 { "d", 0, 0 },
44 { "directory <dir>", I18N_NOOP("Directory to generate files in"), "." },
45 { "+file.kcfg", I18N_NOOP("Input kcfg XML file"), 0 },
46 { "+file.kcfgc", I18N_NOOP("Code generation options file"), 0 },
47 TDECmdLineLastOption
48};
49
50
51bool globalEnums;
52bool itemAccessors;
53bool dpointer;
54TQStringList allNames;
55TQRegExp *validNameRegexp;
56TQString This;
57TQString Const;
58
59class CfgEntry
60{
61 public:
62 struct Choice
63 {
64 TQString name;
65 TQString label;
66 TQString whatsThis;
67 };
68
69 CfgEntry( const TQString &group, const TQString &type, const TQString &key,
70 const TQString &name, const TQString &label,
71 const TQString &whatsThis, const TQString &code,
72 const TQString &defaultValue, const TQValueList<Choice> &choices,
73 bool hidden )
74 : mGroup( group ), mType( type ), mKey( key ), mName( name ),
75 mLabel( label ), mWhatsThis( whatsThis ), mCode( code ),
76 mDefaultValue( defaultValue ),
77 mChoices( choices ), mHidden( hidden )
78 {
79 }
80
81 void setGroup( const TQString &group ) { mGroup = group; }
82 TQString group() const { return mGroup; }
83
84 void setType( const TQString &type ) { mType = type; }
85 TQString type() const { return mType; }
86
87 void setKey( const TQString &key ) { mKey = key; }
88 TQString key() const { return mKey; }
89
90 void setName( const TQString &name ) { mName = name; }
91 TQString name() const { return mName; }
92
93 void setLabel( const TQString &label ) { mLabel = label; }
94 TQString label() const { return mLabel; }
95
96 void setWhatsThis( const TQString &whatsThis ) { mWhatsThis = whatsThis; }
97 TQString whatsThis() const { return mWhatsThis; }
98
99 void setDefaultValue( const TQString &d ) { mDefaultValue = d; }
100 TQString defaultValue() const { return mDefaultValue; }
101
102 void setCode( const TQString &d ) { mCode = d; }
103 TQString code() const { return mCode; }
104
105 void setMinValue( const TQString &d ) { mMin = d; }
106 TQString minValue() const { return mMin; }
107
108 void setMaxValue( const TQString &d ) { mMax = d; }
109 TQString maxValue() const { return mMax; }
110
111 void setParam( const TQString &d ) { mParam = d; }
112 TQString param() const { return mParam; }
113
114 void setParamName( const TQString &d ) { mParamName = d; }
115 TQString paramName() const { return mParamName; }
116
117 void setParamType( const TQString &d ) { mParamType = d; }
118 TQString paramType() const { return mParamType; }
119
120 void setChoices( const TQValueList<Choice> &d ) { mChoices = d; }
121 TQValueList<Choice> choices() const { return mChoices; }
122
123 void setParamValues( const TQStringList &d ) { mParamValues = d; }
124 TQStringList paramValues() const { return mParamValues; }
125
126 void setParamDefaultValues( const TQStringList &d ) { mParamDefaultValues = d; }
127 TQString paramDefaultValue(int i) const { return mParamDefaultValues[i]; }
128
129 void setParamMax( int d ) { mParamMax = d; }
130 int paramMax() const { return mParamMax; }
131
132 bool hidden() const { return mHidden; }
133
134 void dump() const
135 {
136 kdDebug() << "<entry>" << endl;
137 kdDebug() << " group: " << mGroup << endl;
138 kdDebug() << " type: " << mType << endl;
139 kdDebug() << " key: " << mKey << endl;
140 kdDebug() << " name: " << mName << endl;
141 kdDebug() << " label: " << mLabel << endl;
142// whatsthis
143 kdDebug() << " code: " << mCode << endl;
144// kdDebug() << " values: " << mValues.join(":") << endl;
145
146 if (!param().isEmpty())
147 {
148 kdDebug() << " param name: "<< mParamName << endl;
149 kdDebug() << " param type: "<< mParamType << endl;
150 kdDebug() << " paramvalues: " << mParamValues.join(":") << endl;
151 }
152 kdDebug() << " default: " << mDefaultValue << endl;
153 kdDebug() << " hidden: " << mHidden << endl;
154 kdDebug() << " min: " << mMin << endl;
155 kdDebug() << " max: " << mMax << endl;
156 kdDebug() << "</entry>" << endl;
157 }
158
159 private:
160 TQString mGroup;
161 TQString mType;
162 TQString mKey;
163 TQString mName;
164 TQString mLabel;
165 TQString mWhatsThis;
166 TQString mCode;
167 TQString mDefaultValue;
168 TQString mParam;
169 TQString mParamName;
170 TQString mParamType;
171 TQValueList<Choice> mChoices;
172 TQStringList mParamValues;
173 TQStringList mParamDefaultValues;
174 int mParamMax;
175 bool mHidden;
176 TQString mMin;
177 TQString mMax;
178};
179
180class Param {
181public:
182 TQString name;
183 TQString type;
184};
185
186// returns the name of an member variable
187// use itemPath to know the full path
188// like using d-> in case of dpointer
189static TQString varName(const TQString &n)
190{
191 TQString result;
192 if ( !dpointer ) {
193 result = "m"+n;
194 result[1] = result[1].upper();
195 }
196 else {
197 result = n;
198 result[0] = result[0].lower();
199 }
200 return result;
201}
202
203static TQString varPath(const TQString &n)
204{
205 TQString result;
206 if ( dpointer ) {
207 result = "d->"+varName(n);
208 }
209 else {
210 result = varName(n);
211 }
212 return result;
213}
214
215static TQString enumName(const TQString &n)
216{
217 TQString result = "Enum"+n;
218 result[4] = result[4].upper();
219 return result;
220}
221
222static TQString setFunction(const TQString &n, const TQString &className = TQString())
223{
224 TQString result = "set"+n;
225 result[3] = result[3].upper();
226
227 if ( !className.isEmpty() )
228 result = className + "::" + result;
229 return result;
230}
231
232
233static TQString getFunction(const TQString &n, const TQString &className = TQString())
234{
235 TQString result = n;
236 result[0] = result[0].lower();
237
238 if ( !className.isEmpty() )
239 result = className + "::" + result;
240 return result;
241}
242
243
244static void addQuotes( TQString &s )
245{
246 if ( s.left( 1 ) != "\"" ) s.prepend( "\"" );
247 if ( s.right( 1 ) != "\"" ) s.append( "\"" );
248}
249
250static TQString quoteString( const TQString &s )
251{
252 TQString r = s;
253 r.replace( "\\", "\\\\" );
254 r.replace( "\"", "\\\"" );
255 r.replace( "\r", "" );
256 r.replace( "\n", "\\n\"\n\"" );
257 return "\"" + r + "\"";
258}
259
260static TQString literalString( const TQString &s )
261{
262 bool isAscii = true;
263 for(int i = s.length(); i--;)
264 if (s[i].unicode() > 127) isAscii = false;
265
266 if (isAscii)
267 return "TQString::fromLatin1( " + quoteString(s) + " )";
268 else
269 return "TQString::fromUtf8( " + quoteString(s) + " )";
270}
271
272static TQString dumpNode(const TQDomNode &node)
273{
274 TQString msg;
275 TQTextStream s(&msg, IO_WriteOnly );
276 node.save(s, 0);
277
278 msg = msg.simplifyWhiteSpace();
279 if (msg.length() > 40)
280 return msg.left(37)+"...";
281 return msg;
282}
283
284static TQString filenameOnly(TQString path)
285{
286 int i = path.findRev('/');
287 if (i >= 0)
288 return path.mid(i+1);
289 return path;
290}
291
292static void preProcessDefault( TQString &defaultValue, const TQString &name,
293 const TQString &type,
294 const TQValueList<CfgEntry::Choice> &choices,
295 TQString &code )
296{
297 if ( type == "String" && !defaultValue.isEmpty() ) {
298 defaultValue = literalString(defaultValue);
299
300 } else if ( type == "Path" && !defaultValue.isEmpty() ) {
301 defaultValue = literalString( defaultValue );
302
303 } else if ( (type == "StringList" || type == "PathList") && !defaultValue.isEmpty() ) {
304 TQTextStream cpp( &code, IO_WriteOnly | IO_Append );
305 if (!code.isEmpty())
306 cpp << endl;
307
308 cpp << " TQStringList default" << name << ";" << endl;
309 TQStringList defaults = TQStringList::split( ",", defaultValue );
310 TQStringList::ConstIterator it;
311 for( it = defaults.begin(); it != defaults.end(); ++it ) {
312 cpp << " default" << name << ".append( TQString::fromUtf8( \"" << *it << "\" ) );"
313 << endl;
314 }
315 defaultValue = "default" + name;
316
317 } else if ( type == "Color" && !defaultValue.isEmpty() ) {
318 TQRegExp colorRe("\\d+,\\s*\\d+,\\s*\\d+");
319 if (colorRe.exactMatch(defaultValue))
320 {
321 defaultValue = "TQColor( " + defaultValue + " )";
322 }
323 else
324 {
325 defaultValue = "TQColor( \"" + defaultValue + "\" )";
326 }
327
328 } else if ( type == "Enum" ) {
329 if ( !globalEnums ) {
330 TQValueList<CfgEntry::Choice>::ConstIterator it;
331 for( it = choices.begin(); it != choices.end(); ++it ) {
332 if ( (*it).name == defaultValue ) {
333 defaultValue.prepend( enumName(name) + "::");
334 break;
335 }
336 }
337 }
338
339 } else if ( type == "IntList" ) {
340 TQTextStream cpp( &code, IO_WriteOnly | IO_Append );
341 if (!code.isEmpty())
342 cpp << endl;
343
344 cpp << " TQValueList<int> default" << name << ";" << endl;
345 TQStringList defaults = TQStringList::split( ",", defaultValue );
346 TQStringList::ConstIterator it;
347 for( it = defaults.begin(); it != defaults.end(); ++it ) {
348 cpp << " default" << name << ".append( " << *it << " );"
349 << endl;
350 }
351 defaultValue = "default" + name;
352 }
353}
354
355
356CfgEntry *parseEntry( const TQString &group, const TQDomElement &element )
357{
358 bool defaultCode = false;
359 TQString type = element.attribute( "type" );
360 TQString name = element.attribute( "name" );
361 TQString key = element.attribute( "key" );
362 TQString hidden = element.attribute( "hidden" );
363 TQString label;
364 TQString whatsThis;
365 TQString defaultValue;
366 TQString code;
367 TQString param;
368 TQString paramName;
369 TQString paramType;
370 TQValueList<CfgEntry::Choice> choices;
371 TQStringList paramValues;
372 TQStringList paramDefaultValues;
373 TQString minValue;
374 TQString maxValue;
375 int paramMax = 0;
376
377 TQDomNode n;
378 for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
379 TQDomElement e = n.toElement();
380 TQString tag = e.tagName();
381 if ( tag == "label" ) label = e.text();
382 else if ( tag == "whatsthis" ) whatsThis = e.text();
383 else if ( tag == "min" ) minValue = e.text();
384 else if ( tag == "max" ) maxValue = e.text();
385 else if ( tag == "code" ) code = e.text();
386 else if ( tag == "parameter" )
387 {
388 param = e.attribute( "name" );
389 paramType = e.attribute( "type" );
390 if ( param.isEmpty() ) {
391 kdError() << "Parameter must have a name: " << dumpNode(e) << endl;
392 return 0;
393 }
394 if ( paramType.isEmpty() ) {
395 kdError() << "Parameter must have a type: " << dumpNode(e) << endl;
396 return 0;
397 }
398 if ((paramType == "Int") || (paramType == "UInt"))
399 {
400 bool ok;
401 paramMax = e.attribute("max").toInt(&ok);
402 if (!ok)
403 {
404 kdError() << "Integer parameter must have a maximum (e.g. max=\"0\"): " << dumpNode(e) << endl;
405 return 0;
406 }
407 }
408 else if (paramType == "Enum")
409 {
410 TQDomNode n2;
411 for ( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
412 TQDomElement e2 = n2.toElement();
413 if (e2.tagName() == "values")
414 {
415 TQDomNode n3;
416 for ( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
417 TQDomElement e3 = n3.toElement();
418 if (e3.tagName() == "value")
419 {
420 paramValues.append( e3.text() );
421 }
422 }
423 break;
424 }
425 }
426 if (paramValues.isEmpty())
427 {
428 kdError() << "No values specified for parameter '" << param << "'." << endl;
429 return 0;
430 }
431 paramMax = paramValues.count()-1;
432 }
433 else
434 {
435 kdError() << "Parameter '" << param << "' has type " << paramType << " but must be of type int, uint or Enum." << endl;
436 return 0;
437 }
438 }
439 else if ( tag == "default" )
440 {
441 if (e.attribute("param").isEmpty())
442 {
443 defaultValue = e.text();
444 if (e.attribute( "code" ) == "true")
445 defaultCode = true;
446 }
447 }
448 else if ( tag == "choices" ) {
449 TQDomNode n2;
450 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
451 TQDomElement e2 = n2.toElement();
452 if ( e2.tagName() == "choice" ) {
453 TQDomNode n3;
454 CfgEntry::Choice choice;
455 choice.name = e2.attribute( "name" );
456 if ( choice.name.isEmpty() ) {
457 kdError() << "Tag <choice> requires attribute 'name'." << endl;
458 }
459 for( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
460 TQDomElement e3 = n3.toElement();
461 if ( e3.tagName() == "label" ) choice.label = e3.text();
462 if ( e3.tagName() == "whatsthis" ) choice.whatsThis = e3.text();
463 }
464 choices.append( choice );
465 }
466 }
467 }
468 }
469
470 bool nameIsEmpty = name.isEmpty();
471 if ( nameIsEmpty && key.isEmpty() ) {
472 kdError() << "Entry must have a name or a key: " << dumpNode(element) << endl;
473 return 0;
474 }
475
476 if ( key.isEmpty() ) {
477 key = name;
478 }
479
480 if ( nameIsEmpty ) {
481 name = key;
482 name.replace( " ", TQString() );
483 } else if ( name.contains( ' ' ) ) {
484 kdWarning()<<"Entry '"<<name<<"' contains spaces! <name> elements can't contain speces!"<<endl;
485 name.remove( ' ' );
486 }
487
488 if (name.contains("$("))
489 {
490 if (param.isEmpty())
491 {
492 kdError() << "Name may not be parameterized: " << name << endl;
493 return 0;
494 }
495 }
496 else
497 {
498 if (!param.isEmpty())
499 {
500 kdError() << "Name must contain '$(" << param << ")': " << name << endl;
501 return 0;
502 }
503 }
504
505 if ( label.isEmpty() ) {
506 label = key;
507 }
508
509 if ( type.isEmpty() ) type = "String"; // XXX : implicit type might be bad
510
511 if (!param.isEmpty())
512 {
513 // Adjust name
514 paramName = name;
515 name.replace("$("+param+")", TQString());
516 // Lookup defaults for indexed entries
517 for(int i = 0; i <= paramMax; i++)
518 {
519 paramDefaultValues.append(TQString());
520 }
521
522 TQDomNode n;
523 for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
524 TQDomElement e = n.toElement();
525 TQString tag = e.tagName();
526 if ( tag == "default" )
527 {
528 TQString index = e.attribute("param");
529 if (index.isEmpty())
530 continue;
531
532 bool ok;
533 int i = index.toInt(&ok);
534 if (!ok)
535 {
536 i = paramValues.findIndex(index);
537 if (i == -1)
538 {
539 kdError() << "Index '" << index << "' for default value is unknown." << endl;
540 return 0;
541 }
542 }
543
544 if ((i < 0) || (i > paramMax))
545 {
546 kdError() << "Index '" << i << "' for default value is out of range [0, "<< paramMax<<"]." << endl;
547 return 0;
548 }
549
550 TQString tmpDefaultValue = e.text();
551
552 if (e.attribute( "code" ) != "true")
553 preProcessDefault(tmpDefaultValue, name, type, choices, code);
554
555 paramDefaultValues[i] = tmpDefaultValue;
556 }
557 }
558 }
559
560 if (!validNameRegexp->exactMatch(name))
561 {
562 if (nameIsEmpty)
563 kdError() << "The key '" << key << "' can not be used as name for the entry because "
564 "it is not a valid name. You need to specify a valid name for this entry." << endl;
565 else
566 kdError() << "The name '" << name << "' is not a valid name for an entry." << endl;
567 return 0;
568 }
569
570 if (allNames.contains(name))
571 {
572 if (nameIsEmpty)
573 kdError() << "The key '" << key << "' can not be used as name for the entry because "
574 "it does not result in a unique name. You need to specify a unique name for this entry." << endl;
575 else
576 kdError() << "The name '" << name << "' is not unique." << endl;
577 return 0;
578 }
579 allNames.append(name);
580
581 if (!defaultCode)
582 {
583 preProcessDefault(defaultValue, name, type, choices, code);
584 }
585
586 CfgEntry *result = new CfgEntry( group, type, key, name, label, whatsThis,
587 code, defaultValue, choices,
588 hidden == "true" );
589 if (!param.isEmpty())
590 {
591 result->setParam(param);
592 result->setParamName(paramName);
593 result->setParamType(paramType);
594 result->setParamValues(paramValues);
595 result->setParamDefaultValues(paramDefaultValues);
596 result->setParamMax(paramMax);
597 }
598 result->setMinValue(minValue);
599 result->setMaxValue(maxValue);
600
601 return result;
602}
603
607TQString param( const TQString &type )
608{
609 if ( type == "String" ) return "const TQString &";
610 else if ( type == "StringList" ) return "const TQStringList &";
611 else if ( type == "Font" ) return "const TQFont &";
612 else if ( type == "Rect" ) return "const TQRect &";
613 else if ( type == "Size" ) return "const TQSize &";
614 else if ( type == "Color" ) return "const TQColor &";
615 else if ( type == "Point" ) return "const TQPoint &";
616 else if ( type == "Int" ) return "int";
617 else if ( type == "UInt" ) return "uint";
618 else if ( type == "Bool" ) return "bool";
619 else if ( type == "Double" ) return "double";
620 else if ( type == "DateTime" ) return "const TQDateTime &";
621 else if ( type == "Int64" ) return "TQ_INT64";
622 else if ( type == "UInt64" ) return "TQ_UINT64";
623 else if ( type == "IntList" ) return "const TQValueList<int> &";
624 else if ( type == "Enum" ) return "int";
625 else if ( type == "Path" ) return "const TQString &";
626 else if ( type == "PathList" ) return "const TQStringList &";
627 else if ( type == "Password" ) return "const TQString &";
628 else {
629 kdError() <<"tdeconfig_compiler does not support type \""<< type <<"\""<<endl;
630 return "TQString"; //For now, but an assert would be better
631 }
632}
633
637TQString cppType( const TQString &type )
638{
639 if ( type == "String" ) return "TQString";
640 else if ( type == "StringList" ) return "TQStringList";
641 else if ( type == "Font" ) return "TQFont";
642 else if ( type == "Rect" ) return "TQRect";
643 else if ( type == "Size" ) return "TQSize";
644 else if ( type == "Color" ) return "TQColor";
645 else if ( type == "Point" ) return "TQPoint";
646 else if ( type == "Int" ) return "int";
647 else if ( type == "UInt" ) return "uint";
648 else if ( type == "Bool" ) return "bool";
649 else if ( type == "Double" ) return "double";
650 else if ( type == "DateTime" ) return "TQDateTime";
651 else if ( type == "Int64" ) return "TQ_INT64";
652 else if ( type == "UInt64" ) return "TQ_UINT64";
653 else if ( type == "IntList" ) return "TQValueList<int>";
654 else if ( type == "Enum" ) return "int";
655 else if ( type == "Path" ) return "TQString";
656 else if ( type == "PathList" ) return "TQStringList";
657 else if ( type == "Password" ) return "TQString";
658 else {
659 kdError()<<"tdeconfig_compiler does not support type \""<< type <<"\""<<endl;
660 return "TQString"; //For now, but an assert would be better
661 }
662}
663
664TQString defaultValue( const TQString &type )
665{
666 if ( type == "String" ) return "\"\""; // Use empty string, not null string!
667 else if ( type == "StringList" ) return "TQStringList()";
668 else if ( type == "Font" ) return "TDEGlobalSettings::generalFont()";
669 else if ( type == "Rect" ) return "TQRect()";
670 else if ( type == "Size" ) return "TQSize()";
671 else if ( type == "Color" ) return "TQColor(128, 128, 128)";
672 else if ( type == "Point" ) return "TQPoint()";
673 else if ( type == "Int" ) return "0";
674 else if ( type == "UInt" ) return "0";
675 else if ( type == "Bool" ) return "false";
676 else if ( type == "Double" ) return "0.0";
677 else if ( type == "DateTime" ) return "TQDateTime()";
678 else if ( type == "Int64" ) return "0";
679 else if ( type == "UInt64" ) return "0";
680 else if ( type == "IntList" ) return "TQValueList<int>()";
681 else if ( type == "Enum" ) return "0";
682 else if ( type == "Path" ) return "\"\""; // Use empty string, not null string!
683 else if ( type == "PathList" ) return "TQStringList()";
684 else if ( type == "Password" ) return "\"\""; // Use empty string, not null string!
685 else {
686 kdWarning()<<"Error, tdeconfig_compiler doesn't support the \""<< type <<"\" type!"<<endl;
687 return "TQString"; //For now, but an assert would be better
688 }
689}
690
691TQString itemType( const TQString &type )
692{
693 TQString t;
694
695 t = type;
696 t.replace( 0, 1, t.left( 1 ).upper() );
697
698 return t;
699}
700
701static TQString itemDeclaration(const CfgEntry *e)
702{
703 if (itemAccessors)
704 return TQString();
705
706 TQString fCap = e->name();
707 fCap[0] = fCap[0].upper();
708 return " TDEConfigSkeleton::Item"+itemType( e->type() ) +
709 " *item" + fCap +
710 ( (!e->param().isEmpty())?(TQString("[%1]").arg(e->paramMax()+1)) : TQString()) +
711 ";\n";
712}
713
714// returns the name of an item variable
715// use itemPath to know the full path
716// like using d-> in case of dpointer
717static TQString itemVar(const CfgEntry *e)
718{
719 TQString result;
720 if (itemAccessors)
721 {
722 if ( !dpointer )
723 {
724 result = "m" + e->name() + "Item";
725 result[1] = result[1].upper();
726 }
727 else
728 {
729 result = e->name() + "Item";
730 result[0] = result[0].lower();
731 }
732 }
733 else
734 {
735 result = "item" + e->name();
736 result[4] = result[4].upper();
737 }
738 return result;
739}
740
741static TQString itemPath(const CfgEntry *e)
742{
743 TQString result;
744 if ( dpointer ) {
745 result = "d->"+itemVar(e);
746 }
747 else {
748 result = itemVar(e);
749 }
750 return result;
751}
752
753TQString newItem( const TQString &type, const TQString &name, const TQString &key,
754 const TQString &defaultValue, const TQString &param = TQString())
755{
756 TQString t = "new TDEConfigSkeleton::Item" + itemType( type ) +
757 "( currentGroup(), " + key + ", " + varPath( name ) + param;
758 if ( type == "Enum" ) t += ", values" + name;
759 if ( !defaultValue.isEmpty() ) {
760 t += ", ";
761 if ( type == "String" ) t += defaultValue;
762 else t+= defaultValue;
763 }
764 t += " );";
765
766 return t;
767}
768
769TQString paramString(const TQString &s, const CfgEntry *e, int i)
770{
771 TQString result = s;
772 TQString needle = "$("+e->param()+")";
773 if (result.contains(needle))
774 {
775 TQString tmp;
776 if (e->paramType() == "Enum")
777 {
778 tmp = e->paramValues()[i];
779 }
780 else
781 {
782 tmp = TQString::number(i);
783 }
784
785 result.replace(needle, tmp);
786 }
787 return result;
788}
789
790TQString paramString(const TQString &group, const TQValueList<Param> &parameters)
791{
792 TQString paramString = group;
793 TQString arguments;
794 int i = 1;
795 for (TQValueList<Param>::ConstIterator it = parameters.begin();
796 it != parameters.end(); ++it)
797 {
798 if (paramString.contains("$("+(*it).name+")"))
799 {
800 TQString tmp;
801 tmp.sprintf("%%%d", i++);
802 paramString.replace("$("+(*it).name+")", tmp);
803 arguments += ".arg( mParam"+(*it).name+" )";
804 }
805 }
806 if (arguments.isEmpty())
807 return "TQString::fromLatin1( \""+group+"\" )";
808
809 return "TQString::fromLatin1( \""+paramString+"\" )"+arguments;
810}
811
812/* int i is the value of the parameter */
813TQString userTextsFunctions( CfgEntry *e, TQString itemVarStr=TQString(), TQString i=TQString() )
814{
815 TQString txt;
816 if (itemVarStr.isNull()) itemVarStr=itemPath(e);
817 if ( !e->label().isEmpty() ) {
818 txt += " " + itemVarStr + "->setLabel( i18n(";
819 if ( !e->param().isEmpty() )
820 txt += quoteString(e->label().replace("$("+e->param()+")", i));
821 else
822 txt+= quoteString(e->label());
823 txt+= ") );\n";
824 }
825 if ( !e->whatsThis().isEmpty() ) {
826 txt += " " + itemVarStr + "->setWhatsThis( i18n(";
827 if ( !e->param().isEmpty() )
828 txt += quoteString(e->whatsThis().replace("$("+e->param()+")", i));
829 else
830 txt+= quoteString(e->whatsThis());
831 txt+=") );\n";
832 }
833 return txt;
834}
835
836// returns the member accesor implementation
837// which should go in the h file if inline
838// or the cpp file if not inline
839TQString memberAccessorBody( CfgEntry *e )
840{
841 TQString result;
842 TQTextStream out(&result, IO_WriteOnly);
843 TQString n = e->name();
844 TQString t = e->type();
845
846 out << "return " << This << varPath(n);
847 if (!e->param().isEmpty()) out << "[i]";
848 out << ";" << endl;
849
850 return result;
851}
852
853// returns the member mutator implementation
854// which should go in the h file if inline
855// or the cpp file if not inline
856TQString memberMutatorBody( CfgEntry *e )
857{
858 TQString result;
859 TQTextStream out(&result, IO_WriteOnly);
860 TQString n = e->name();
861 TQString t = e->type();
862
863 if (!e->minValue().isEmpty())
864 {
865 out << "if (v < " << e->minValue() << ")" << endl;
866 out << "{" << endl;
867 out << " kdDebug() << \"" << setFunction(n);
868 out << ": value \" << v << \" is less than the minimum value of ";
869 out << e->minValue()<< "\" << endl;" << endl;
870 out << " v = " << e->minValue() << ";" << endl;
871 out << "}" << endl;
872 }
873
874 if (!e->maxValue().isEmpty())
875 {
876 out << endl << "if (v > " << e->maxValue() << ")" << endl;
877 out << "{" << endl;
878 out << " kdDebug() << \"" << setFunction(n);
879 out << ": value \" << v << \" is greater than the maximum value of ";
880 out << e->maxValue()<< "\" << endl;" << endl;
881 out << " v = " << e->maxValue() << ";" << endl;
882 out << "}" << endl << endl;
883 }
884
885 out << "if (!" << This << "isImmutable( TQString::fromLatin1( \"";
886 if (!e->param().isEmpty())
887 {
888 out << e->paramName().replace("$("+e->param()+")", "%1") << "\" ).arg( ";
889 if ( e->paramType() == "Enum" ) {
890 out << "TQString::fromLatin1( ";
891
892 if (globalEnums)
893 out << enumName(e->param()) << "ToString[i]";
894 else
895 out << enumName(e->param()) << "::enumToString[i]";
896
897 out << " )";
898 }
899 else
900 {
901 out << "i";
902 }
903 out << " )";
904 }
905 else
906 {
907 out << n << "\" )";
908 }
909 out << " ))" << endl;
910 out << " " << This << varPath(n);
911 if (!e->param().isEmpty())
912 out << "[i]";
913 out << " = v;" << endl;
914
915 return result;
916}
917
918// returns the item accesor implementation
919// which should go in the h file if inline
920// or the cpp file if not inline
921TQString itemAccessorBody( CfgEntry *e )
922{
923 TQString result;
924 TQTextStream out(&result, IO_WriteOnly);
925
926 out << "return " << itemPath(e);
927 if (!e->param().isEmpty()) out << "[i]";
928 out << ";" << endl;
929
930 return result;
931}
932
933//indents text adding X spaces per line
934TQString indent(TQString text, int spaces)
935{
936 TQString result;
937 TQTextStream out(&result, IO_WriteOnly);
938 TQTextStream in(&text, IO_ReadOnly);
939 TQString currLine;
940 while ( !in.atEnd() )
941 {
942 currLine = in.readLine();
943 if (!currLine.isEmpty())
944 for (int i=0; i < spaces; i++)
945 out << " ";
946 out << currLine << endl;
947 }
948 return result;
949}
950
951
952int main( int argc, char **argv )
953{
954 TDEAboutData aboutData( "tdeconfig_compiler", I18N_NOOP("TDE .kcfg compiler"), "0.3",
955 I18N_NOOP("TDEConfig Compiler") , TDEAboutData::License_LGPL );
956 aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
957 aboutData.addAuthor( "Waldo Bastian", 0, "bastian@kde.org" );
958 aboutData.addAuthor( "Zack Rusin", 0, "zack@kde.org" );
959 aboutData.addCredit( "Reinhold Kainhofer", "Fix for parametrized entries",
960 "reinhold@kainhofer.com", "http://reinhold.kainhofer.com" );
961 aboutData.addCredit( "Duncan Mac-Vicar P.", "dpointer support",
962 "duncan@kde.org", "http://www.mac-vicar.com/~duncan" );
963
964 TDECmdLineArgs::init( argc, argv, &aboutData );
965 TDECmdLineArgs::addCmdLineOptions( options );
966
967 TDEInstance app( &aboutData );
968
969 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
970
971 if ( args->count() < 2 ) {
972 kdError() << "Too few arguments." << endl;
973 return 1;
974 }
975 if ( args->count() > 2 ) {
976 kdError() << "Too many arguments." << endl;
977 return 1;
978 }
979
980 validNameRegexp = new TQRegExp("[a-zA-Z_][a-zA-Z0-9_]*");
981
982 TQString baseDir = TQFile::decodeName(args->getOption("directory"));
983 if (!baseDir.endsWith("/"))
984 baseDir.append("/");
985
986 TQString inputFilename = args->url( 0 ).path();
987 TQString codegenFilename = args->url( 1 ).path();
988
989 if (!codegenFilename.endsWith(".kcfgc"))
990 {
991 kdError() << "Codegen options file must have extension .kcfgc" << endl;
992 return 1;
993 }
994 TQString baseName = args->url( 1 ).fileName();
995 baseName = baseName.left(baseName.length() - 6);
996
997 KSimpleConfig codegenConfig( codegenFilename, true );
998
999 TQString nameSpace = codegenConfig.readEntry("NameSpace");
1000 TQString className = codegenConfig.readEntry("ClassName");
1001 TQString inherits = codegenConfig.readEntry("Inherits");
1002 TQString visibility = codegenConfig.readEntry("Visibility");
1003 if (!visibility.isEmpty()) visibility+=" ";
1004 bool singleton = codegenConfig.readBoolEntry("Singleton", false);
1005 bool staticAccessors = singleton;
1006 //bool useDPointer = codegenConfig.readBoolEntry("DPointer", false);
1007 bool customAddons = codegenConfig.readBoolEntry("CustomAdditions");
1008 TQString memberVariables = codegenConfig.readEntry("MemberVariables");
1009 TQStringList headerIncludes = codegenConfig.readListEntry("IncludeFiles");
1010 TQStringList mutators = codegenConfig.readListEntry("Mutators");
1011 bool allMutators = false;
1012 if ((mutators.count() == 1) && (mutators[0].lower() == "true"))
1013 allMutators = true;
1014 itemAccessors = codegenConfig.readBoolEntry( "ItemAccessors", false );
1015 bool setUserTexts = codegenConfig.readBoolEntry( "SetUserTexts", false );
1016
1017 globalEnums = codegenConfig.readBoolEntry( "GlobalEnums", false );
1018
1019 dpointer = (memberVariables == "dpointer");
1020
1021 TQFile input( inputFilename );
1022
1023 TQDomDocument doc;
1024 TQString errorMsg;
1025 int errorRow;
1026 int errorCol;
1027 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
1028 kdError() << "Unable to load document." << endl;
1029 kdError() << "Parse error in " << args->url( 0 ).fileName() << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl;
1030 return 1;
1031 }
1032
1033 TQDomElement cfgElement = doc.documentElement();
1034
1035 if ( cfgElement.isNull() ) {
1036 kdError() << "No document in kcfg file" << endl;
1037 return 1;
1038 }
1039
1040 TQString cfgFileName;
1041 bool cfgFileNameArg = false;
1042 TQValueList<Param> parameters;
1043 TQStringList includes;
1044
1045 TQPtrList<CfgEntry> entries;
1046 entries.setAutoDelete( true );
1047
1048 TQDomNode n;
1049 for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
1050 TQDomElement e = n.toElement();
1051
1052 TQString tag = e.tagName();
1053
1054 if ( tag == "include" ) {
1055 TQString includeFile = e.text();
1056 if (!includeFile.isEmpty())
1057 includes.append(includeFile);
1058
1059 } else if ( tag == "kcfgfile" ) {
1060 cfgFileName = e.attribute( "name" );
1061 cfgFileNameArg = e.attribute( "arg" ).lower() == "true";
1062 TQDomNode n2;
1063 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
1064 TQDomElement e2 = n2.toElement();
1065 if ( e2.tagName() == "parameter" ) {
1066 Param p;
1067 p.name = e2.attribute( "name" );
1068 p.type = e2.attribute( "type" );
1069 if (p.type.isEmpty())
1070 p.type = "String";
1071 parameters.append( p );
1072 }
1073 }
1074
1075 } else if ( tag == "group" ) {
1076 TQString group = e.attribute( "name" );
1077 if ( group.isEmpty() ) {
1078 kdError() << "Group without name" << endl;
1079 return 1;
1080 }
1081 TQDomNode n2;
1082 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
1083 TQDomElement e2 = n2.toElement();
1084 if ( e2.tagName() != "entry" ) continue;
1085 CfgEntry *entry = parseEntry( group, e2 );
1086 if ( entry ) entries.append( entry );
1087 else {
1088 kdError() << "Can't parse entry." << endl;
1089 return 1;
1090 }
1091 }
1092 }
1093 }
1094
1095 if ( inherits.isEmpty() ) inherits = "TDEConfigSkeleton";
1096
1097 if ( className.isEmpty() ) {
1098 kdError() << "Class name missing" << endl;
1099 return 1;
1100 }
1101
1102 if ( singleton && !parameters.isEmpty() ) {
1103 kdError() << "Singleton class can not have parameters" << endl;
1104 return 1;
1105 }
1106
1107 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
1108 {
1109 kdError() << "Having both a fixed filename and a filename as argument is not possible." << endl;
1110 return 1;
1111 }
1112
1113 if ( entries.isEmpty() ) {
1114 kdWarning() << "No entries." << endl;
1115 }
1116
1117#if 0
1118 CfgEntry *cfg;
1119 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
1120 cfg->dump();
1121 }
1122#endif
1123
1124 TQString headerFileName = baseName + ".h";
1125 TQString implementationFileName = baseName + ".cpp";
1126 TQString cppPreamble; // code to be inserted at the beginnin of the cpp file, e.g. initialization of static values
1127
1128 TQFile header( baseDir + headerFileName );
1129 if ( !header.open( IO_WriteOnly ) ) {
1130 kdError() << "Can't open '" << headerFileName << "' for writing." << endl;
1131 return 1;
1132 }
1133
1134 TQTextStream h( &header );
1135
1136 h << "// This file is generated by tdeconfig_compiler from " << args->url(0).fileName() << "." << endl;
1137 h << "// All changes you do to this file will be lost." << endl;
1138
1139 h << "#ifndef " << ( !nameSpace.isEmpty() ? nameSpace.upper() + "_" : "" )
1140 << className.upper() << "_H" << endl;
1141 h << "#define " << ( !nameSpace.isEmpty() ? nameSpace.upper() + "_" : "" )
1142 << className.upper() << "_H" << endl << endl;
1143
1144 // Includes
1145 TQStringList::ConstIterator it;
1146 for( it = headerIncludes.begin(); it != headerIncludes.end(); ++it ) {
1147 h << "#include <" << *it << ">" << endl;
1148 }
1149
1150 if ( headerIncludes.count() > 0 ) h << endl;
1151
1152 if ( !singleton && cfgFileNameArg && parameters.isEmpty() )
1153 h << "#include <tdeglobal.h>" << endl;
1154
1155 h << "#include <tdeconfigskeleton.h>" << endl;
1156 h << "#include <kdebug.h>" << endl << endl;
1157
1158 // Includes
1159 for( it = includes.begin(); it != includes.end(); ++it ) {
1160 h << "#include <" << *it << ">" << endl;
1161 }
1162
1163
1164 if ( !nameSpace.isEmpty() )
1165 h << "namespace " << nameSpace << " {" << endl << endl;
1166
1167 // Private class declaration
1168 if ( dpointer )
1169 h << "class " << className << "Private;" << endl << endl;
1170
1171 // Class declaration header
1172 h << "class " << visibility << className << " : public " << inherits << endl;
1173 h << "{" << endl;
1174 h << " public:" << endl;
1175
1176 // enums
1177 CfgEntry *e;
1178 for( e = entries.first(); e; e = entries.next() ) {
1179 TQValueList<CfgEntry::Choice> choices = e->choices();
1180 if ( !choices.isEmpty() ) {
1181 TQStringList values;
1182 TQValueList<CfgEntry::Choice>::ConstIterator itChoice;
1183 for( itChoice = choices.begin(); itChoice != choices.end(); ++itChoice ) {
1184 values.append( (*itChoice).name );
1185 }
1186 if ( globalEnums ) {
1187 h << " enum { " << values.join( ", " ) << " };" << endl;
1188 } else {
1189 h << " class " << enumName(e->name()) << endl;
1190 h << " {" << endl;
1191 h << " public:" << endl;
1192 h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl;
1193 h << " };" << endl;
1194 }
1195 }
1196 TQStringList values = e->paramValues();
1197 if ( !values.isEmpty() ) {
1198 if ( globalEnums ) {
1199 h << " enum { " << values.join( ", " ) << " };" << endl;
1200 h << " static const char* const " << enumName(e->param()) << "ToString[];" << endl;
1201 cppPreamble += "const char* const " + className + "::" + enumName(e->param()) + "ToString[] = " +
1202 "{ \"" + values.join( "\", \"" ) + "\" };\n";
1203 } else {
1204 h << " class " << enumName(e->param()) << endl;
1205 h << " {" << endl;
1206 h << " public:" << endl;
1207 h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl;
1208 h << " static const char* const enumToString[];" << endl;
1209 h << " };" << endl;
1210 cppPreamble += "const char* const " + className + "::" + enumName(e->param()) + "::enumToString[] = " +
1211 "{ \"" + values.join( "\", \"" ) + "\" };\n";
1212 }
1213 }
1214 }
1215
1216 h << endl;
1217
1218 // Constructor or singleton accessor
1219 if ( !singleton ) {
1220 h << " " << className << "(";
1221 if (cfgFileNameArg)
1222 h << " TDESharedConfig::Ptr config" << (parameters.isEmpty() ? " = TDEGlobal::sharedConfig()" : ", ");
1223 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1224 it != parameters.end(); ++it)
1225 {
1226 if (it != parameters.begin())
1227 h << ",";
1228 h << " " << param((*it).type) << " " << (*it).name;
1229 }
1230 h << " );" << endl;
1231 } else {
1232 h << " static " << className << " *self();" << endl;
1233 if (cfgFileNameArg)
1234 h << " static void instance(const char * cfgfilename);" << endl;
1235 }
1236
1237 // Destructor
1238 h << " ~" << className << "();" << endl << endl;
1239
1240 // global variables
1241 if (staticAccessors)
1242 This = "self()->";
1243 else
1244 Const = " const";
1245
1246 for( e = entries.first(); e; e = entries.next() ) {
1247 TQString n = e->name();
1248 TQString t = e->type();
1249
1250 // Manipulator
1251 if (allMutators || mutators.contains(n))
1252 {
1253 h << " /**" << endl;
1254 h << " Set " << e->label() << endl;
1255 h << " */" << endl;
1256 if (staticAccessors)
1257 h << " static" << endl;
1258 h << " void " << setFunction(n) << "( ";
1259 if (!e->param().isEmpty())
1260 h << cppType(e->paramType()) << " i, ";
1261 h << param( t ) << " v )";
1262 // function body inline only if not using dpointer
1263 // for BC mode
1264 if ( !dpointer )
1265 {
1266 h << endl << " {" << endl;
1267 h << indent(memberMutatorBody(e), 6 );
1268 h << " }" << endl;
1269 }
1270 else
1271 {
1272 h << ";" << endl;
1273 }
1274 }
1275 h << endl;
1276 // Accessor
1277 h << " /**" << endl;
1278 h << " Get " << e->label() << endl;
1279 h << " */" << endl;
1280 if (staticAccessors)
1281 h << " static" << endl;
1282 h << " " << cppType(t) << " " << getFunction(n) << "(";
1283 if (!e->param().isEmpty())
1284 h << " " << cppType(e->paramType()) <<" i ";
1285 h << ")" << Const;
1286 // function body inline only if not using dpointer
1287 // for BC mode
1288 if ( !dpointer )
1289 {
1290 h << endl << " {" << endl;
1291 h << indent(memberAccessorBody(e), 6 );
1292 h << " }" << endl;
1293 }
1294 else
1295 {
1296 h << ";" << endl;
1297 }
1298
1299 // Item accessor
1300 if ( itemAccessors ) {
1301 h << endl;
1302 h << " /**" << endl;
1303 h << " Get Item object corresponding to " << n << "()"
1304 << endl;
1305 h << " */" << endl;
1306 h << " Item" << itemType( e->type() ) << " *"
1307 << getFunction( n ) << "Item(";
1308 if (!e->param().isEmpty()) {
1309 h << " " << cppType(e->paramType()) << " i ";
1310 }
1311 h << ")";
1312 if (! dpointer )
1313 {
1314 h << endl << " {" << endl;
1315 h << indent( itemAccessorBody(e), 6);
1316 h << " }" << endl;
1317 }
1318 else
1319 {
1320 h << ";" << endl;
1321 }
1322 }
1323
1324 h << endl;
1325 }
1326
1327 // Static writeConfig method for singleton
1328 if ( singleton ) {
1329 h << " static" << endl;
1330 h << " void writeConfig()" << endl;
1331 h << " {" << endl;
1332 h << " static_cast<TDEConfigSkeleton*>(self())->writeConfig();" << endl;
1333 h << " }" << endl;
1334 }
1335
1336 h << " protected:" << endl;
1337
1338 // Private constructor for singleton
1339 if ( singleton ) {
1340 h << " " << className << "(";
1341 if ( cfgFileNameArg )
1342 h << "const char *arg";
1343 h << ");" << endl;
1344 h << " static " << className << " *mSelf;" << endl << endl;
1345 }
1346
1347 // Member variables
1348 if ( !memberVariables.isEmpty() && memberVariables != "private" && memberVariables != "dpointer") {
1349 h << " " << memberVariables << ":" << endl;
1350 }
1351
1352 // Class Parameters
1353 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1354 it != parameters.end(); ++it)
1355 {
1356 h << " " << cppType((*it).type) << " mParam" << (*it).name << ";" << endl;
1357 }
1358
1359 if ( memberVariables != "dpointer" )
1360 {
1361 TQString group;
1362 for( e = entries.first(); e; e = entries.next() ) {
1363 if ( e->group() != group ) {
1364 group = e->group();
1365 h << endl;
1366 h << " // " << group << endl;
1367 }
1368 h << " " << cppType(e->type()) << " " << varName(e->name());
1369 if (!e->param().isEmpty())
1370 {
1371 h << TQString("[%1]").arg(e->paramMax()+1);
1372 }
1373 h << ";" << endl;
1374 }
1375
1376 h << endl << " private:" << endl;
1377 if ( itemAccessors ) {
1378 for( e = entries.first(); e; e = entries.next() ) {
1379 h << " Item" << itemType( e->type() ) << " *" << itemVar( e );
1380 if (!e->param().isEmpty() ) h << TQString("[%1]").arg( e->paramMax()+1 );
1381 h << ";" << endl;
1382 }
1383 }
1384
1385 }
1386 else
1387 {
1388 // use a private class for both member variables and items
1389 h << " private:" << endl;
1390 h << " " + className + "Private *d;" << endl;
1391 }
1392
1393 if (customAddons)
1394 {
1395 h << " // Include custom additions" << endl;
1396 h << " #include \"" << filenameOnly(baseName) << "_addons.h\"" <<endl;
1397 }
1398
1399 h << "};" << endl << endl;
1400
1401 if ( !nameSpace.isEmpty() ) h << "}" << endl << endl;
1402
1403 h << "#endif" << endl << endl;
1404
1405
1406 header.close();
1407
1408 TQFile implementation( baseDir + implementationFileName );
1409 if ( !implementation.open( IO_WriteOnly ) ) {
1410 kdError() << "Can't open '" << implementationFileName << "' for writing."
1411 << endl;
1412 return 1;
1413 }
1414
1415 TQTextStream cpp( &implementation );
1416
1417
1418 cpp << "// This file is generated by tdeconfig_compiler from " << args->url(0).fileName() << "." << endl;
1419 cpp << "// All changes you do to this file will be lost." << endl << endl;
1420
1421 cpp << "#include \"" << headerFileName << "\"" << endl << endl;
1422
1423 if ( setUserTexts ) cpp << "#include <tdelocale.h>" << endl << endl;
1424
1425 // Header required by singleton implementation
1426 if ( singleton )
1427 cpp << "#include <kstaticdeleter.h>" << endl << endl;
1428 if ( singleton && cfgFileNameArg )
1429 cpp << "#include <kdebug.h>" << endl << endl;
1430
1431 if ( !nameSpace.isEmpty() )
1432 cpp << "using namespace " << nameSpace << ";" << endl << endl;
1433
1434 TQString group;
1435
1436 // private class implementation
1437 if ( dpointer )
1438 {
1439 cpp << "class " << className << "Private" << endl;
1440 cpp << "{" << endl;
1441 cpp << " public:" << endl;
1442 for( e = entries.first(); e; e = entries.next() ) {
1443 if ( e->group() != group ) {
1444 group = e->group();
1445 cpp << endl;
1446 cpp << " // " << group << endl;
1447 }
1448 cpp << " " << cppType(e->type()) << " " << varName(e->name());
1449 if (!e->param().isEmpty())
1450 {
1451 cpp << TQString("[%1]").arg(e->paramMax()+1);
1452 }
1453 cpp << ";" << endl;
1454 }
1455 cpp << endl << " // items" << endl;
1456 for( e = entries.first(); e; e = entries.next() ) {
1457 cpp << " TDEConfigSkeleton::Item" << itemType( e->type() ) << " *" << itemVar( e );
1458 if (!e->param().isEmpty() ) cpp << TQString("[%1]").arg( e->paramMax()+1 );
1459 cpp << ";" << endl;
1460 }
1461
1462 cpp << "};" << endl << endl;
1463 }
1464
1465 // Singleton implementation
1466 if ( singleton ) {
1467 cpp << className << " *" << className << "::mSelf = 0;" << endl;
1468 cpp << "static KStaticDeleter<" << className << "> static" << className << "Deleter;" << endl << endl;
1469
1470 cpp << className << " *" << className << "::self()" << endl;
1471 cpp << "{" << endl;
1472 if ( cfgFileNameArg ) {
1473 cpp << " if (!mSelf)" << endl;
1474 cpp << " kdFatal() << \"you need to call " << className << "::instance before using\" << endl;" << endl;
1475 } else {
1476 cpp << " if ( !mSelf ) {" << endl;
1477 cpp << " static" << className << "Deleter.setObject( mSelf, new " << className << "() );" << endl;
1478 cpp << " mSelf->readConfig();" << endl;
1479 cpp << " }" << endl << endl;
1480 }
1481 cpp << " return mSelf;" << endl;
1482 cpp << "}" << endl << endl;
1483
1484 if ( cfgFileNameArg ) {
1485 cpp << "void " << className << "::instance(const char *cfgfilename)" << endl;
1486 cpp << "{" << endl;
1487 cpp << " if (mSelf) {" << endl;
1488 cpp << " kdError() << \"" << className << "::instance called after the first use - ignoring\" << endl;" << endl;
1489 cpp << " return;" << endl;
1490 cpp << " }" << endl;
1491 cpp << " static" << className << "Deleter.setObject( mSelf, new " << className << "(cfgfilename) );" << endl;
1492 cpp << " mSelf->readConfig();" << endl;
1493 cpp << "}" << endl << endl;
1494 }
1495 }
1496
1497 if ( !cppPreamble.isEmpty() )
1498 cpp << cppPreamble << endl;
1499
1500 // Constructor
1501 cpp << className << "::" << className << "( ";
1502 if ( cfgFileNameArg ) {
1503 if ( !singleton )
1504 cpp << " TDESharedConfig::Ptr config";
1505 else
1506 cpp << " const char *config";
1507 cpp << (parameters.isEmpty() ? " " : ", ");
1508 }
1509
1510 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1511 it != parameters.end(); ++it)
1512 {
1513 if (it != parameters.begin())
1514 cpp << ",";
1515 cpp << " " << param((*it).type) << " " << (*it).name;
1516 }
1517 cpp << " )" << endl;
1518
1519 cpp << " : " << inherits << "(";
1520 if ( !cfgFileName.isEmpty() ) cpp << " TQString::fromLatin1( \"" << cfgFileName << "\" ";
1521 if ( cfgFileNameArg ) cpp << " config ";
1522 if ( !cfgFileName.isEmpty() ) cpp << ") ";
1523 cpp << ")" << endl;
1524
1525 // Store parameters
1526 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1527 it != parameters.end(); ++it)
1528 {
1529 cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl;
1530 }
1531
1532 cpp << "{" << endl;
1533
1534 if (dpointer)
1535 cpp << " d = new " + className + "Private;" << endl;
1536 // Needed in case the singleton class is used as baseclass for
1537 // another singleton.
1538 if ( singleton )
1539 cpp << " mSelf = this;" << endl;
1540
1541 group = TQString();
1542 for( e = entries.first(); e; e = entries.next() ) {
1543 if ( e->group() != group ) {
1544 if ( !group.isEmpty() ) cpp << endl;
1545 group = e->group();
1546 cpp << " setCurrentGroup( " << paramString(group, parameters) << " );" << endl << endl;
1547 }
1548
1549 TQString key = paramString(e->key(), parameters);
1550 if ( !e->code().isEmpty())
1551 {
1552 cpp << e->code() << endl;
1553 }
1554 if ( e->type() == "Enum" ) {
1555 cpp << " TQValueList<TDEConfigSkeleton::ItemEnum::Choice> values"
1556 << e->name() << ";" << endl;
1557 TQValueList<CfgEntry::Choice> choices = e->choices();
1558 TQValueList<CfgEntry::Choice>::ConstIterator it;
1559 for( it = choices.begin(); it != choices.end(); ++it ) {
1560 cpp << " {" << endl;
1561 cpp << " TDEConfigSkeleton::ItemEnum::Choice choice;" << endl;
1562 cpp << " choice.name = TQString::fromLatin1( \"" << (*it).name << "\" );" << endl;
1563 if ( setUserTexts ) {
1564 if ( !(*it).label.isEmpty() )
1565 cpp << " choice.label = i18n(" << quoteString((*it).label) << ");" << endl;
1566 if ( !(*it).whatsThis.isEmpty() )
1567 cpp << " choice.whatsThis = i18n(" << quoteString((*it).whatsThis) << ");" << endl;
1568 }
1569 cpp << " values" << e->name() << ".append( choice );" << endl;
1570 cpp << " }" << endl;
1571 }
1572 }
1573
1574 if (!dpointer)
1575 cpp << itemDeclaration(e);
1576
1577 if (e->param().isEmpty())
1578 {
1579 // Normal case
1580 cpp << " " << itemPath(e) << " = "
1581 << newItem( e->type(), e->name(), key, e->defaultValue() ) << endl;
1582
1583 if ( !e->minValue().isEmpty() )
1584 cpp << " " << itemPath(e) << "->setMinValue(" << e->minValue() << ");" << endl;
1585 if ( !e->maxValue().isEmpty() )
1586 cpp << " " << itemPath(e) << "->setMaxValue(" << e->maxValue() << ");" << endl;
1587
1588 if ( setUserTexts )
1589 cpp << userTextsFunctions( e );
1590
1591 cpp << " addItem( " << itemPath(e);
1592 TQString quotedName = e->name();
1593 addQuotes( quotedName );
1594 if ( quotedName != key ) cpp << ", TQString::fromLatin1( \"" << e->name() << "\" )";
1595 cpp << " );" << endl;
1596 }
1597 else
1598 {
1599 // Indexed
1600 for(int i = 0; i <= e->paramMax(); i++)
1601 {
1602 TQString defaultStr;
1603 TQString itemVarStr(itemPath(e)+TQString("[%1]").arg(i));
1604
1605 if ( !e->paramDefaultValue(i).isEmpty() )
1606 defaultStr = e->paramDefaultValue(i);
1607 else if ( !e->defaultValue().isEmpty() )
1608 defaultStr = paramString(e->defaultValue(), e, i);
1609 else
1610 defaultStr = defaultValue( e->type() );
1611
1612 cpp << " " << itemVarStr << " = "
1613 << newItem( e->type(), e->name(), paramString(key, e, i), defaultStr, TQString("[%1]").arg(i) )
1614 << endl;
1615
1616 if ( setUserTexts )
1617 cpp << userTextsFunctions( e, itemVarStr, e->paramName() );
1618
1619 // Make mutators for enum parameters work by adding them with $(..) replaced by the
1620 // param name. The check for isImmutable in the set* functions doesn't have the param
1621 // name available, just the corresponding enum value (int), so we need to store the
1622 // param names in a separate static list!.
1623 cpp << " addItem( " << itemVarStr << ", TQString::fromLatin1( \"";
1624 if ( e->paramType()=="Enum" )
1625 cpp << e->paramName().replace( "$("+e->param()+")", "%1").arg(e->paramValues()[i] );
1626 else
1627 cpp << e->paramName().replace( "$("+e->param()+")", "%1").arg(i);
1628 cpp << "\" ) );" << endl;
1629 }
1630 }
1631 }
1632
1633 cpp << "}" << endl << endl;
1634
1635 if (dpointer)
1636 {
1637 // setters and getters go in Cpp if in dpointer mode
1638 for( e = entries.first(); e; e = entries.next() )
1639 {
1640 TQString n = e->name();
1641 TQString t = e->type();
1642
1643 // Manipulator
1644 if (allMutators || mutators.contains(n))
1645 {
1646 cpp << "void " << setFunction(n, className) << "( ";
1647 if (!e->param().isEmpty())
1648 cpp << cppType(e->paramType()) << " i, ";
1649 cpp << param( t ) << " v )" << endl;
1650 // function body inline only if not using dpointer
1651 // for BC mode
1652 cpp << "{" << endl;
1653 cpp << indent(memberMutatorBody(e), 6);
1654 cpp << "}" << endl << endl;
1655 }
1656
1657 // Accessor
1658 cpp << cppType(t) << " " << getFunction(n, className) << "(";
1659 if (!e->param().isEmpty())
1660 cpp << " " << cppType(e->paramType()) <<" i ";
1661 cpp << ")" << Const << endl;
1662 // function body inline only if not using dpointer
1663 // for BC mode
1664 cpp << "{" << endl;
1665 cpp << indent(memberAccessorBody(e), 2);
1666 cpp << "}" << endl << endl;
1667
1668 // Item accessor
1669 if ( itemAccessors )
1670 {
1671 cpp << endl;
1672 cpp << "TDEConfigSkeleton::Item" << itemType( e->type() ) << " *"
1673 << getFunction( n, className ) << "Item(";
1674 if (!e->param().isEmpty()) {
1675 cpp << " " << cppType(e->paramType()) << " i ";
1676 }
1677 cpp << ")" << endl;
1678 cpp << "{" << endl;
1679 cpp << indent(itemAccessorBody(e), 2);
1680 cpp << "}" << endl;
1681 }
1682
1683 cpp << endl;
1684 }
1685 }
1686
1687 // Destructor
1688 cpp << className << "::~" << className << "()" << endl;
1689 cpp << "{" << endl;
1690 if ( singleton ) {
1691 if ( dpointer )
1692 cpp << " delete d;" << endl;
1693 cpp << " if ( mSelf == this )" << endl;
1694 cpp << " static" << className << "Deleter.setObject( mSelf, 0, false );" << endl;
1695 }
1696 cpp << "}" << endl << endl;
1697
1698 implementation.close();
1699}
KSimpleConfig
KDE Configuration entries.
Definition: ksimpleconfig.h:42
KURL::path
TQString path() const
Returns the current decoded path.
Definition: kurl.h:532
KURL::fileName
TQString fileName(bool _ignore_trailing_slash_in_path=true) const
Returns the filename of the path.
Definition: kurl.cpp:1709
TDEAboutData
This class is used to store information about a program.
Definition: tdeaboutdata.h:183
TDEAction::text
virtual TQString text() const
TDECmdLineArgs
A class for command-line argument handling.
Definition: tdecmdlineargs.h:223
TDECmdLineArgs::parsedArgs
static TDECmdLineArgs * parsedArgs(const char *id=0)
Access parsed arguments.
Definition: tdecmdlineargs.cpp:310
TDECmdLineArgs::addCmdLineOptions
static void addCmdLineOptions(const TDECmdLineOptions *options, const char *name=0, const char *id=0, const char *afterId=0)
Add options to your application.
Definition: tdecmdlineargs.cpp:206
TDECmdLineArgs::url
KURL url(int n) const
Read out an argument representing a URL.
Definition: tdecmdlineargs.cpp:1248
TDECmdLineArgs::getOption
TQCString getOption(const char *option) const
Read out a string option.
Definition: tdecmdlineargs.cpp:1119
TDECmdLineArgs::init
static void init(int _argc, char **_argv, const char *_appname, const char *programName, const char *_description, const char *_version, bool noTDEApp=false)
Initialize class.
Definition: tdecmdlineargs.cpp:127
TDECmdLineArgs::count
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
Definition: tdecmdlineargs.cpp:1224
TDEInstance
Access to KDE global objects for use in shared libraries.
Definition: kinstance.h:48
TDELocale::I18N_NOOP
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
Definition: tdelocale.h:51
TDEGlobal::kdWarning
kdbgstream kdWarning(int area=0)
Returns a warning stream.
Definition: kdebug.cpp:376
TDEGlobal::kdError
kdbgstream kdError(int area=0)
Returns an error stream.
Definition: kdebug.cpp:374
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
TDEGlobal::endl
kdbgstream & endl(kdbgstream &s)
Prints an "\n".
Definition: kdebug.h:430
KStdAction::whatsThis
TDEAction * whatsThis(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
KStdAction::name
const char * name(StdAction id)
TDEStdAccel::key
int key(StdAccel id)
Definition: tdestdaccel.cpp:383
TDEStdAccel::label
TQString label(StdAccel id)
Returns a localized label for user-visible display.
Definition: tdestdaccel.cpp:156
TDECmdLineOptions
Structure that holds command line options.
Definition: tdecmdlineargs.h:41
tdelocale.h

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.