diff options
Diffstat (limited to 'src/kconfig_compiler/kconfig_compiler.cpp')
-rw-r--r-- | src/kconfig_compiler/kconfig_compiler.cpp | 3885 |
1 files changed, 2053 insertions, 1832 deletions
diff --git a/src/kconfig_compiler/kconfig_compiler.cpp b/src/kconfig_compiler/kconfig_compiler.cpp index ae192eec..bdbd03c3 100644 --- a/src/kconfig_compiler/kconfig_compiler.cpp +++ b/src/kconfig_compiler/kconfig_compiler.cpp @@ -1,4 +1,3 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*- /* This file is part of KDE. @@ -42,8 +41,8 @@ namespace { - QTextStream cout(stdout); - QTextStream cerr(stderr); +QTextStream cout(stdout); +QTextStream cerr(stderr); } static void parseArgs(const QStringList &args, QString &directory, QString &file1, QString &file2) @@ -109,236 +108,379 @@ QString Const; class CfgConfig { public: - CfgConfig( const QString &codegenFilename ) - { - // Configure the compiler with some settings - QSettings codegenConfig(codegenFilename, QSettings::IniFormat); - - nameSpace = codegenConfig.value("NameSpace").toString(); - className = codegenConfig.value("ClassName").toString(); - if ( className.isEmpty() ) { - cerr << "Class name missing" << endl; - exit(1); - } - inherits = codegenConfig.value("Inherits").toString(); - if ( inherits.isEmpty() ) inherits = "KConfigSkeleton"; - visibility = codegenConfig.value("Visibility").toString(); - if ( !visibility.isEmpty() ) visibility += ' '; - forceStringFilename = codegenConfig.value("ForceStringFilename", false).toBool(); - singleton = codegenConfig.value("Singleton", false).toBool(); - staticAccessors = singleton; - customAddons = codegenConfig.value("CustomAdditions", false).toBool(); - memberVariables = codegenConfig.value("MemberVariables").toString(); - dpointer = (memberVariables == "dpointer"); - headerIncludes = codegenConfig.value("IncludeFiles", QStringList()).toStringList(); - sourceIncludes = codegenConfig.value("SourceIncludeFiles", QStringList()).toStringList(); - mutators = codegenConfig.value("Mutators", QStringList()).toStringList(); - allMutators = ((mutators.count() == 1) && (mutators.at(0).toLower() == "true")); - itemAccessors = codegenConfig.value("ItemAccessors", false).toBool(); - setUserTexts = codegenConfig.value("SetUserTexts", false).toBool(); - defaultGetters = codegenConfig.value("DefaultValueGetters", QStringList()).toStringList(); - allDefaultGetters = (defaultGetters.count() == 1) && (defaultGetters.at(0).toLower() == "true"); - globalEnums = codegenConfig.value("GlobalEnums", false).toBool(); - useEnumTypes = codegenConfig.value("UseEnumTypes", false).toBool(); - - const QString trString = codegenConfig.value("TranslationSystem").toString().toLower(); - if ( trString == "kde" ) { - translationSystem = KdeTranslation; - } else { - if ( !trString.isEmpty() && trString != "qt" ) { - cerr << "Unknown translation system, falling back to Qt tr()" << endl; + CfgConfig(const QString &codegenFilename) + { + // Configure the compiler with some settings + QSettings codegenConfig(codegenFilename, QSettings::IniFormat); + + nameSpace = codegenConfig.value("NameSpace").toString(); + className = codegenConfig.value("ClassName").toString(); + if (className.isEmpty()) { + cerr << "Class name missing" << endl; + exit(1); + } + inherits = codegenConfig.value("Inherits").toString(); + if (inherits.isEmpty()) { + inherits = "KConfigSkeleton"; + } + visibility = codegenConfig.value("Visibility").toString(); + if (!visibility.isEmpty()) { + visibility += ' '; + } + forceStringFilename = codegenConfig.value("ForceStringFilename", false).toBool(); + singleton = codegenConfig.value("Singleton", false).toBool(); + staticAccessors = singleton; + customAddons = codegenConfig.value("CustomAdditions", false).toBool(); + memberVariables = codegenConfig.value("MemberVariables").toString(); + dpointer = (memberVariables == "dpointer"); + headerIncludes = codegenConfig.value("IncludeFiles", QStringList()).toStringList(); + sourceIncludes = codegenConfig.value("SourceIncludeFiles", QStringList()).toStringList(); + mutators = codegenConfig.value("Mutators", QStringList()).toStringList(); + allMutators = ((mutators.count() == 1) && (mutators.at(0).toLower() == "true")); + itemAccessors = codegenConfig.value("ItemAccessors", false).toBool(); + setUserTexts = codegenConfig.value("SetUserTexts", false).toBool(); + defaultGetters = codegenConfig.value("DefaultValueGetters", QStringList()).toStringList(); + allDefaultGetters = (defaultGetters.count() == 1) && (defaultGetters.at(0).toLower() == "true"); + globalEnums = codegenConfig.value("GlobalEnums", false).toBool(); + useEnumTypes = codegenConfig.value("UseEnumTypes", false).toBool(); + + const QString trString = codegenConfig.value("TranslationSystem").toString().toLower(); + if (trString == "kde") { + translationSystem = KdeTranslation; + } else { + if (!trString.isEmpty() && trString != "qt") { + cerr << "Unknown translation system, falling back to Qt tr()" << endl; + } + translationSystem = QtTranslation; } - translationSystem = QtTranslation; } - } public: - enum TranslationSystem { - QtTranslation, - KdeTranslation - }; - - // These are read from the .kcfgc configuration file - QString nameSpace; // The namespace for the class to be generated - QString className; // The class name to be generated - QString inherits; // The class the generated class inherits (if empty, from KConfigSkeleton) - QString visibility; - bool forceStringFilename; - bool singleton; // The class will be a singleton - bool staticAccessors; // provide or not static accessors - bool customAddons; - QString memberVariables; - QStringList headerIncludes; - QStringList sourceIncludes; - QStringList mutators; - QStringList defaultGetters; - bool allMutators; - bool setUserTexts; - bool allDefaultGetters; - bool dpointer; - bool globalEnums; - bool useEnumTypes; - bool itemAccessors; - TranslationSystem translationSystem; -}; + enum TranslationSystem { + QtTranslation, + KdeTranslation + }; + // These are read from the .kcfgc configuration file + QString nameSpace; // The namespace for the class to be generated + QString className; // The class name to be generated + QString inherits; // The class the generated class inherits (if empty, from KConfigSkeleton) + QString visibility; + bool forceStringFilename; + bool singleton; // The class will be a singleton + bool staticAccessors; // provide or not static accessors + bool customAddons; + QString memberVariables; + QStringList headerIncludes; + QStringList sourceIncludes; + QStringList mutators; + QStringList defaultGetters; + bool allMutators; + bool setUserTexts; + bool allDefaultGetters; + bool dpointer; + bool globalEnums; + bool useEnumTypes; + bool itemAccessors; + TranslationSystem translationSystem; +}; -struct SignalArguments -{ - QString type; - QString variableName; +struct SignalArguments { + QString type; + QString variableName; }; -class Signal { +class Signal +{ public: - QString name; - QString label; - QList<SignalArguments> arguments; + QString name; + QString label; + QList<SignalArguments> arguments; }; - - - class CfgEntry { - public: - struct Choice - { - QString name; - QString context; - QString label; - QString toolTip; - QString whatsThis; +public: + struct Choice { + QString name; + QString context; + QString label; + QString toolTip; + QString whatsThis; }; class Choices { - public: + public: Choices() {} - Choices( const QList<Choice> &d, const QString &n, const QString &p ) - : prefix(p), choices(d), mName(n) + Choices(const QList<Choice> &d, const QString &n, const QString &p) + : prefix(p), choices(d), mName(n) { - int i = n.indexOf(QLatin1String("::")); - if (i >= 0) - mExternalQual = n.left(i + 2); + int i = n.indexOf(QLatin1String("::")); + if (i >= 0) { + mExternalQual = n.left(i + 2); + } } QString prefix; QList<Choice> choices; - const QString& name() const { return mName; } - const QString& externalQualifier() const { return mExternalQual; } - bool external() const { return !mExternalQual.isEmpty(); } - private: + const QString &name() const + { + return mName; + } + const QString &externalQualifier() const + { + return mExternalQual; + } + bool external() const + { + return !mExternalQual.isEmpty(); + } + private: QString mName; QString mExternalQual; }; - CfgEntry( const QString &group, const QString &type, const QString &key, - const QString &name, const QString &labelContext, const QString &label, - const QString &toolTipContext, const QString &toolTip, const QString &whatsThisContext, const QString &whatsThis, const QString &code, - const QString &defaultValue, const Choices &choices, const QList<Signal> signalList, - bool hidden ) - : mGroup( group ), mType( type ), mKey( key ), mName( name ), - mLabelContext( labelContext ), mLabel( label ), mToolTipContext( toolTipContext ), mToolTip( toolTip ), - mWhatsThisContext( whatsThisContext ), mWhatsThis( whatsThis ), - mCode( code ), mDefaultValue( defaultValue ), mChoices( choices ), - mSignalList(signalList), mHidden( hidden ) + CfgEntry(const QString &group, const QString &type, const QString &key, + const QString &name, const QString &labelContext, const QString &label, + const QString &toolTipContext, const QString &toolTip, const QString &whatsThisContext, const QString &whatsThis, const QString &code, + const QString &defaultValue, const Choices &choices, const QList<Signal> signalList, + bool hidden) + : mGroup(group), mType(type), mKey(key), mName(name), + mLabelContext(labelContext), mLabel(label), mToolTipContext(toolTipContext), mToolTip(toolTip), + mWhatsThisContext(whatsThisContext), mWhatsThis(whatsThis), + mCode(code), mDefaultValue(defaultValue), mChoices(choices), + mSignalList(signalList), mHidden(hidden) { } - void setGroup( const QString &group ) { mGroup = group; } - QString group() const { return mGroup; } + void setGroup(const QString &group) + { + mGroup = group; + } + QString group() const + { + return mGroup; + } - void setType( const QString &type ) { mType = type; } - QString type() const { return mType; } + void setType(const QString &type) + { + mType = type; + } + QString type() const + { + return mType; + } - void setKey( const QString &key ) { mKey = key; } - QString key() const { return mKey; } + void setKey(const QString &key) + { + mKey = key; + } + QString key() const + { + return mKey; + } - void setName( const QString &name ) { mName = name; } - QString name() const { return mName; } + void setName(const QString &name) + { + mName = name; + } + QString name() const + { + return mName; + } - void setLabelContext( const QString &labelContext ) { mLabelContext = labelContext; } - QString labelContext() const { return mLabelContext; } + void setLabelContext(const QString &labelContext) + { + mLabelContext = labelContext; + } + QString labelContext() const + { + return mLabelContext; + } - void setLabel( const QString &label ) { mLabel = label; } - QString label() const { return mLabel; } + void setLabel(const QString &label) + { + mLabel = label; + } + QString label() const + { + return mLabel; + } - void setToolTipContext( const QString &toolTipContext ) { mToolTipContext = toolTipContext; } - QString toolTipContext() const { return mToolTipContext; } + void setToolTipContext(const QString &toolTipContext) + { + mToolTipContext = toolTipContext; + } + QString toolTipContext() const + { + return mToolTipContext; + } - void setToolTip( const QString &toolTip ) { mToolTip = toolTip; } - QString toolTip() const { return mToolTip; } + void setToolTip(const QString &toolTip) + { + mToolTip = toolTip; + } + QString toolTip() const + { + return mToolTip; + } - void setWhatsThisContext( const QString &whatsThisContext ) { mWhatsThisContext = whatsThisContext; } - QString whatsThisContext() const { return mWhatsThisContext; } + void setWhatsThisContext(const QString &whatsThisContext) + { + mWhatsThisContext = whatsThisContext; + } + QString whatsThisContext() const + { + return mWhatsThisContext; + } - void setWhatsThis( const QString &whatsThis ) { mWhatsThis = whatsThis; } - QString whatsThis() const { return mWhatsThis; } + void setWhatsThis(const QString &whatsThis) + { + mWhatsThis = whatsThis; + } + QString whatsThis() const + { + return mWhatsThis; + } - void setDefaultValue( const QString &d ) { mDefaultValue = d; } - QString defaultValue() const { return mDefaultValue; } + void setDefaultValue(const QString &d) + { + mDefaultValue = d; + } + QString defaultValue() const + { + return mDefaultValue; + } - void setCode( const QString &d ) { mCode = d; } - QString code() const { return mCode; } + void setCode(const QString &d) + { + mCode = d; + } + QString code() const + { + return mCode; + } - void setMinValue( const QString &d ) { mMin = d; } - QString minValue() const { return mMin; } + void setMinValue(const QString &d) + { + mMin = d; + } + QString minValue() const + { + return mMin; + } - void setMaxValue( const QString &d ) { mMax = d; } - QString maxValue() const { return mMax; } + void setMaxValue(const QString &d) + { + mMax = d; + } + QString maxValue() const + { + return mMax; + } - void setParam( const QString &d ) { mParam = d; } - QString param() const { return mParam; } + void setParam(const QString &d) + { + mParam = d; + } + QString param() const + { + return mParam; + } - void setParamName( const QString &d ) { mParamName = d; } - QString paramName() const { return mParamName; } + void setParamName(const QString &d) + { + mParamName = d; + } + QString paramName() const + { + return mParamName; + } - void setParamType( const QString &d ) { mParamType = d; } - QString paramType() const { return mParamType; } + void setParamType(const QString &d) + { + mParamType = d; + } + QString paramType() const + { + return mParamType; + } - void setChoices( const QList<Choice> &d, const QString &n, const QString &p ) { mChoices = Choices( d, n, p ); } - Choices choices() const { return mChoices; } + void setChoices(const QList<Choice> &d, const QString &n, const QString &p) + { + mChoices = Choices(d, n, p); + } + Choices choices() const + { + return mChoices; + } - void setParamValues( const QStringList &d ) { mParamValues = d; } - QStringList paramValues() const { return mParamValues; } + void setParamValues(const QStringList &d) + { + mParamValues = d; + } + QStringList paramValues() const + { + return mParamValues; + } - void setParamDefaultValues( const QStringList &d ) { mParamDefaultValues = d; } - QString paramDefaultValue(int i) const { return mParamDefaultValues[i]; } + void setParamDefaultValues(const QStringList &d) + { + mParamDefaultValues = d; + } + QString paramDefaultValue(int i) const + { + return mParamDefaultValues[i]; + } - void setParamMax( int d ) { mParamMax = d; } - int paramMax() const { return mParamMax; } + void setParamMax(int d) + { + mParamMax = d; + } + int paramMax() const + { + return mParamMax; + } - void setSignalList( const QList<Signal> &value ) { mSignalList = value; } - QList<Signal> signalList() const { return mSignalList; } + void setSignalList(const QList<Signal> &value) + { + mSignalList = value; + } + QList<Signal> signalList() const + { + return mSignalList; + } - bool hidden() const { return mHidden; } + bool hidden() const + { + return mHidden; + } void dump() const { - cerr << "<entry>" << endl; - cerr << " group: " << mGroup << endl; - cerr << " type: " << mType << endl; - cerr << " key: " << mKey << endl; - cerr << " name: " << mName << endl; - cerr << " label context: " << mLabelContext << endl; - cerr << " label: " << mLabel << endl; + cerr << "<entry>" << endl; + cerr << " group: " << mGroup << endl; + cerr << " type: " << mType << endl; + cerr << " key: " << mKey << endl; + cerr << " name: " << mName << endl; + cerr << " label context: " << mLabelContext << endl; + cerr << " label: " << mLabel << endl; // whatsthis - cerr << " code: " << mCode << endl; + cerr << " code: " << mCode << endl; // cerr << " values: " << mValues.join(":") << endl; - if (!param().isEmpty()) - { - cerr << " param name: "<< mParamName << endl; - cerr << " param type: "<< mParamType << endl; - cerr << " paramvalues: " << mParamValues.join(QChar::fromLatin1(':')) << endl; - } - cerr << " default: " << mDefaultValue << endl; - cerr << " hidden: " << mHidden << endl; - cerr << " min: " << mMin << endl; - cerr << " max: " << mMax << endl; - cerr << "</entry>" << endl; + if (!param().isEmpty()) { + cerr << " param name: " << mParamName << endl; + cerr << " param type: " << mParamType << endl; + cerr << " paramvalues: " << mParamValues.join(QChar::fromLatin1(':')) << endl; + } + cerr << " default: " << mDefaultValue << endl; + cerr << " hidden: " << mHidden << endl; + cerr << " min: " << mMin << endl; + cerr << " max: " << mMax << endl; + cerr << "</entry>" << endl; } - private: +private: QString mGroup; QString mType; QString mKey; @@ -364,10 +506,11 @@ class CfgEntry QString mMax; }; -class Param { +class Param +{ public: - QString name; - QString type; + QString name; + QString type; }; // returns the name of an member variable @@ -375,558 +518,562 @@ public: // like using d-> in case of dpointer static QString varName(const QString &n, const CfgConfig &cfg) { - QString result; - if ( !cfg.dpointer ) { - result = QChar::fromLatin1('m') + n; - result[1] = result[1].toUpper(); - } - else { - result = n; - result[0] = result[0].toLower(); - } - return result; + QString result; + if (!cfg.dpointer) { + result = QChar::fromLatin1('m') + n; + result[1] = result[1].toUpper(); + } else { + result = n; + result[0] = result[0].toLower(); + } + return result; } static QString varPath(const QString &n, const CfgConfig &cfg) { - QString result; - if ( cfg.dpointer ) { - result = "d->"+varName(n, cfg); - } - else { - result = varName(n, cfg); - } - return result; + QString result; + if (cfg.dpointer) { + result = "d->" + varName(n, cfg); + } else { + result = varName(n, cfg); + } + return result; } static QString enumName(const QString &n) { - QString result = QString::fromLatin1("Enum") + n; - result[4] = result[4].toUpper(); - return result; + QString result = QString::fromLatin1("Enum") + n; + result[4] = result[4].toUpper(); + return result; } static QString enumName(const QString &n, const CfgEntry::Choices &c) { - QString result = c.name(); - if ( result.isEmpty() ) - { - result = QString::fromLatin1("Enum") + n; - result[4] = result[4].toUpper(); - } - return result; + QString result = c.name(); + if (result.isEmpty()) { + result = QString::fromLatin1("Enum") + n; + result[4] = result[4].toUpper(); + } + return result; } static QString enumType(const CfgEntry *e, bool globalEnums) { - QString result = e->choices().name(); - if ( result.isEmpty() ) - { - result = QString::fromLatin1("Enum") + e->name(); - if( !globalEnums ) - result += QString::fromLatin1("::type"); - result[4] = result[4].toUpper(); - } - return result; + QString result = e->choices().name(); + if (result.isEmpty()) { + result = QString::fromLatin1("Enum") + e->name(); + if (!globalEnums) { + result += QString::fromLatin1("::type"); + } + result[4] = result[4].toUpper(); + } + return result; } static QString enumTypeQualifier(const QString &n, const CfgEntry::Choices &c) { - QString result = c.name(); - if ( result.isEmpty() ) - { - result = QString::fromLatin1("Enum") + n + QString::fromLatin1("::"); - result[4] = result[4].toUpper(); - } - else if ( c.external() ) - result = c.externalQualifier(); - else - result.clear(); - return result; + QString result = c.name(); + if (result.isEmpty()) { + result = QString::fromLatin1("Enum") + n + QString::fromLatin1("::"); + result[4] = result[4].toUpper(); + } else if (c.external()) { + result = c.externalQualifier(); + } else { + result.clear(); + } + return result; } static QString setFunction(const QString &n, const QString &className = QString()) { - QString result = QString::fromLatin1("set") + n; - result[3] = result[3].toUpper(); + QString result = QString::fromLatin1("set") + n; + result[3] = result[3].toUpper(); - if ( !className.isEmpty() ) - result = className + QString::fromLatin1("::") + result; - return result; + if (!className.isEmpty()) { + result = className + QString::fromLatin1("::") + result; + } + return result; } static QString getDefaultFunction(const QString &n, const QString &className = QString()) { - QString result = QString::fromLatin1("default") + n + QString::fromLatin1("Value"); - result[7] = result[7].toUpper(); + QString result = QString::fromLatin1("default") + n + QString::fromLatin1("Value"); + result[7] = result[7].toUpper(); - if ( !className.isEmpty() ) - result = className + QString::fromLatin1("::") + result; - return result; + if (!className.isEmpty()) { + result = className + QString::fromLatin1("::") + result; + } + return result; } static QString getFunction(const QString &n, const QString &className = QString()) { - QString result = n; - result[0] = result[0].toLower(); + QString result = n; + result[0] = result[0].toLower(); - if ( !className.isEmpty() ) - result = className + QString::fromLatin1("::") + result; - return result; + if (!className.isEmpty()) { + result = className + QString::fromLatin1("::") + result; + } + return result; } - -static void addQuotes( QString &s ) +static void addQuotes(QString &s) { - if ( !s.startsWith( QLatin1Char('"') ) ) - s.prepend( QLatin1Char('"') ); - if ( !s.endsWith( QLatin1Char('"') ) ) - s.append( QLatin1Char('"') ); + if (!s.startsWith(QLatin1Char('"'))) { + s.prepend(QLatin1Char('"')); + } + if (!s.endsWith(QLatin1Char('"'))) { + s.append(QLatin1Char('"')); + } } -static QString quoteString( const QString &s ) +static QString quoteString(const QString &s) { - QString r = s; - r.replace( QLatin1Char('\\'), QLatin1String("\\\\") ); - r.replace( QLatin1Char('\"'), QLatin1String("\\\"") ); - r.remove( QLatin1Char('\r') ); - r.replace( QLatin1Char('\n'), QLatin1String("\\n\"\n\"") ); - return QLatin1Char('\"') + r + QLatin1Char('\"'); + QString r = s; + r.replace(QLatin1Char('\\'), QLatin1String("\\\\")); + r.replace(QLatin1Char('\"'), QLatin1String("\\\"")); + r.remove(QLatin1Char('\r')); + r.replace(QLatin1Char('\n'), QLatin1String("\\n\"\n\"")); + return QLatin1Char('\"') + r + QLatin1Char('\"'); } -static QString literalString( const QString &s ) +static QString literalString(const QString &s) { - bool isAscii = true; - for(int i = s.length(); i--;) - if (s[i].unicode() > 127) isAscii = false; - - if (isAscii) - return QString::fromLatin1("QLatin1String( ") + quoteString(s) + QString::fromLatin1(" )"); - else - return QString::fromLatin1("QString::fromUtf8( ") + quoteString(s) + QString::fromLatin1(" )"); + bool isAscii = true; + for (int i = s.length(); i--;) + if (s[i].unicode() > 127) { + isAscii = false; + } + + if (isAscii) { + return QString::fromLatin1("QLatin1String( ") + quoteString(s) + QString::fromLatin1(" )"); + } else { + return QString::fromLatin1("QString::fromUtf8( ") + quoteString(s) + QString::fromLatin1(" )"); + } } static QString dumpNode(const QDomNode &node) { - QString msg; - QTextStream s(&msg, QIODevice::WriteOnly ); - node.save(s, 0); - - msg = msg.simplified(); - if (msg.length() > 40) - return msg.left(37) + QString::fromLatin1("..."); - return msg; + QString msg; + QTextStream s(&msg, QIODevice::WriteOnly); + node.save(s, 0); + + msg = msg.simplified(); + if (msg.length() > 40) { + return msg.left(37) + QString::fromLatin1("..."); + } + return msg; } -static QString filenameOnly(const QString& path) +static QString filenameOnly(const QString &path) { - int i = path.lastIndexOf(QRegExp(QLatin1String("[/\\]"))); - if (i >= 0) - return path.mid(i+1); - return path; + int i = path.lastIndexOf(QRegExp(QLatin1String("[/\\]"))); + if (i >= 0) { + return path.mid(i + 1); + } + return path; } static QString signalEnumName(const QString &signalName) { - QString result; - result = QString::fromLatin1("signal") + signalName; - result[6] = result[6].toUpper(); + QString result; + result = QString::fromLatin1("signal") + signalName; + result[6] = result[6].toUpper(); - return result; + return result; } -static void preProcessDefault( QString &defaultValue, const QString &name, - const QString &type, - const CfgEntry::Choices &choices, - QString &code, const CfgConfig &cfg ) +static void preProcessDefault(QString &defaultValue, const QString &name, + const QString &type, + const CfgEntry::Choices &choices, + QString &code, const CfgConfig &cfg) { - if ( type == QLatin1String("String") && !defaultValue.isEmpty() ) { - defaultValue = literalString(defaultValue); - - } else if ( type == QLatin1String("Path") && !defaultValue.isEmpty() ) { - defaultValue = literalString( defaultValue ); - } else if ( type == QLatin1String("Url") && !defaultValue.isEmpty() ) { - // Use fromUserInput in order to support absolute paths and absolute urls, like KDE4's KUrl(QString) did. - defaultValue = QString::fromLatin1("QUrl::fromUserInput( ") + literalString(defaultValue) + QLatin1Char(')'); - } else if ( ( type == QLatin1String("UrlList") || type == QLatin1String("StringList") || type == QLatin1String("PathList")) && !defaultValue.isEmpty() ) { - QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append ); - if (!code.isEmpty()) - cpp << endl; - - if( type == "UrlList" ) { - cpp << " QList<QUrl> default" << name << ";" << endl; - } else { - cpp << " QStringList default" << name << ";" << endl; - } - const QStringList defaults = defaultValue.split(QLatin1Char(',')); - QStringList::ConstIterator it; - for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) { - cpp << " default" << name << ".append( "; - if( type == QLatin1String("UrlList") ) { - cpp << "QUrl::fromUserInput("; - } - cpp << "QString::fromUtf8( \"" << *it << "\" ) "; - if( type == QLatin1String("UrlList") ) { - cpp << ") "; - } - cpp << ");" << endl; - } - defaultValue = QString::fromLatin1("default") + name; - - } else if ( type == QLatin1String("Color") && !defaultValue.isEmpty() ) { - QRegExp colorRe(QLatin1String("\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?")); - if (colorRe.exactMatch(defaultValue)) - { - defaultValue = QLatin1String("QColor( ") + defaultValue + QLatin1String(" )"); - } - else - { - defaultValue = QLatin1String("QColor( \"") + defaultValue + QLatin1String("\" )"); - } - - } else if ( type == QLatin1String("Enum") ) { - QList<CfgEntry::Choice>::ConstIterator it; - for( it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it ) { - if ( (*it).name == defaultValue ) { - if ( cfg.globalEnums && choices.name().isEmpty() ) - defaultValue.prepend( choices.prefix ); - else - defaultValue.prepend( enumTypeQualifier(name, choices) + choices.prefix ); - break; - } - } - - } else if ( type == QLatin1String("IntList") ) { - QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append ); - if (!code.isEmpty()) - cpp << endl; - - cpp << " QList<int> default" << name << ";" << endl; - if (!defaultValue.isEmpty()) - { - const QStringList defaults = defaultValue.split( QLatin1Char(',') ); + if (type == QLatin1String("String") && !defaultValue.isEmpty()) { + defaultValue = literalString(defaultValue); + + } else if (type == QLatin1String("Path") && !defaultValue.isEmpty()) { + defaultValue = literalString(defaultValue); + } else if (type == QLatin1String("Url") && !defaultValue.isEmpty()) { + // Use fromUserInput in order to support absolute paths and absolute urls, like KDE4's KUrl(QString) did. + defaultValue = QString::fromLatin1("QUrl::fromUserInput( ") + literalString(defaultValue) + QLatin1Char(')'); + } else if ((type == QLatin1String("UrlList") || type == QLatin1String("StringList") || type == QLatin1String("PathList")) && !defaultValue.isEmpty()) { + QTextStream cpp(&code, QIODevice::WriteOnly | QIODevice::Append); + if (!code.isEmpty()) { + cpp << endl; + } + + if (type == "UrlList") { + cpp << " QList<QUrl> default" << name << ";" << endl; + } else { + cpp << " QStringList default" << name << ";" << endl; + } + const QStringList defaults = defaultValue.split(QLatin1Char(',')); QStringList::ConstIterator it; - for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) { - cpp << " default" << name << ".append( " << *it << " );" - << endl; + for (it = defaults.constBegin(); it != defaults.constEnd(); ++it) { + cpp << " default" << name << ".append( "; + if (type == QLatin1String("UrlList")) { + cpp << "QUrl::fromUserInput("; + } + cpp << "QString::fromUtf8( \"" << *it << "\" ) "; + if (type == QLatin1String("UrlList")) { + cpp << ") "; + } + cpp << ");" << endl; + } + defaultValue = QString::fromLatin1("default") + name; + + } else if (type == QLatin1String("Color") && !defaultValue.isEmpty()) { + QRegExp colorRe(QLatin1String("\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?")); + if (colorRe.exactMatch(defaultValue)) { + defaultValue = QLatin1String("QColor( ") + defaultValue + QLatin1String(" )"); + } else { + defaultValue = QLatin1String("QColor( \"") + defaultValue + QLatin1String("\" )"); + } + + } else if (type == QLatin1String("Enum")) { + QList<CfgEntry::Choice>::ConstIterator it; + for (it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it) { + if ((*it).name == defaultValue) { + if (cfg.globalEnums && choices.name().isEmpty()) { + defaultValue.prepend(choices.prefix); + } else { + defaultValue.prepend(enumTypeQualifier(name, choices) + choices.prefix); + } + break; + } + } + + } else if (type == QLatin1String("IntList")) { + QTextStream cpp(&code, QIODevice::WriteOnly | QIODevice::Append); + if (!code.isEmpty()) { + cpp << endl; + } + + cpp << " QList<int> default" << name << ";" << endl; + if (!defaultValue.isEmpty()) { + const QStringList defaults = defaultValue.split(QLatin1Char(',')); + QStringList::ConstIterator it; + for (it = defaults.constBegin(); it != defaults.constEnd(); ++it) { + cpp << " default" << name << ".append( " << *it << " );" + << endl; + } } - } - defaultValue = QString::fromLatin1("default") + name; + defaultValue = QString::fromLatin1("default") + name; } } - -CfgEntry *parseEntry( const QString &group, const QDomElement &element, const CfgConfig &cfg ) +CfgEntry *parseEntry(const QString &group, const QDomElement &element, const CfgConfig &cfg) { - bool defaultCode = false; - QString type = element.attribute( "type" ); - QString name = element.attribute( "name" ); - QString key = element.attribute( "key" ); - QString hidden = element.attribute( "hidden" ); - QString labelContext; - QString label; - QString toolTipContext; - QString toolTip; - QString whatsThisContext; - QString whatsThis; - QString defaultValue; - QString code; - QString param; - QString paramName; - QString paramType; - CfgEntry::Choices choices; - QList<Signal> signalList; - QStringList paramValues; - QStringList paramDefaultValues; - QString minValue; - QString maxValue; - int paramMax = 0; - - for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) { - QString tag = e.tagName(); - if ( tag == "label" ) { - label = e.text(); - labelContext = e.attribute( "context" ); - } - else if ( tag == "tooltip" ) { - toolTip = e.text(); - toolTipContext = e.attribute( "context" ); - } - else if ( tag == "whatsthis" ) { - whatsThis = e.text(); - whatsThisContext = e.attribute( "context" ); - } - else if ( tag == "min" ) minValue = e.text(); - else if ( tag == "max" ) maxValue = e.text(); - else if ( tag == "code" ) code = e.text(); - else if ( tag == "parameter" ) - { - param = e.attribute( "name" ); - paramType = e.attribute( "type" ); - if ( param.isEmpty() ) { - cerr << "Parameter must have a name: " << dumpNode(e) << endl; - return 0; - } - if ( paramType.isEmpty() ) { - cerr << "Parameter must have a type: " << dumpNode(e) << endl; - return 0; - } - if ((paramType == "Int") || (paramType == "UInt")) - { - bool ok; - paramMax = e.attribute("max").toInt(&ok); - if (!ok) - { - cerr << "Integer parameter must have a maximum (e.g. max=\"0\"): " - << dumpNode(e) << endl; - return 0; - } - } - else if (paramType == "Enum") - { - for ( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) { - if (e2.tagName() == "values") - { - for ( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) { - if (e3.tagName() == "value") - { - paramValues.append( e3.text() ); - } - } - break; - } - } - if (paramValues.isEmpty()) - { - cerr << "No values specified for parameter '" << param - << "'." << endl; - return 0; - } - paramMax = paramValues.count()-1; - } - else - { - cerr << "Parameter '" << param << "' has type " << paramType - << " but must be of type int, uint or Enum." << endl; - return 0; - } - } - else if ( tag == "default" ) - { - if (e.attribute("param").isEmpty()) - { - defaultValue = e.text(); - if (e.attribute( "code" ) == "true") - defaultCode = true; - } - } - else if ( tag == "choices" ) { - QString name = e.attribute( "name" ); - QString prefix = e.attribute( "prefix" ); - QList<CfgEntry::Choice> chlist; - for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) { - if ( e2.tagName() == "choice" ) { - CfgEntry::Choice choice; - choice.name = e2.attribute( "name" ); - if ( choice.name.isEmpty() ) { - cerr << "Tag <choice> requires attribute 'name'." << endl; - } - for( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) { - if ( e3.tagName() == "label" ) { - choice.label = e3.text(); - choice.context = e3.attribute( "context" ); + bool defaultCode = false; + QString type = element.attribute("type"); + QString name = element.attribute("name"); + QString key = element.attribute("key"); + QString hidden = element.attribute("hidden"); + QString labelContext; + QString label; + QString toolTipContext; + QString toolTip; + QString whatsThisContext; + QString whatsThis; + QString defaultValue; + QString code; + QString param; + QString paramName; + QString paramType; + CfgEntry::Choices choices; + QList<Signal> signalList; + QStringList paramValues; + QStringList paramDefaultValues; + QString minValue; + QString maxValue; + int paramMax = 0; + + for (QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { + QString tag = e.tagName(); + if (tag == "label") { + label = e.text(); + labelContext = e.attribute("context"); + } else if (tag == "tooltip") { + toolTip = e.text(); + toolTipContext = e.attribute("context"); + } else if (tag == "whatsthis") { + whatsThis = e.text(); + whatsThisContext = e.attribute("context"); + } else if (tag == "min") { + minValue = e.text(); + } else if (tag == "max") { + maxValue = e.text(); + } else if (tag == "code") { + code = e.text(); + } else if (tag == "parameter") { + param = e.attribute("name"); + paramType = e.attribute("type"); + if (param.isEmpty()) { + cerr << "Parameter must have a name: " << dumpNode(e) << endl; + return 0; } - if ( e3.tagName() == "tooltip" ) { - choice.toolTip = e3.text(); - choice.context = e3.attribute( "context" ); + if (paramType.isEmpty()) { + cerr << "Parameter must have a type: " << dumpNode(e) << endl; + return 0; } - if ( e3.tagName() == "whatsthis" ) { - choice.whatsThis = e3.text(); - choice.context = e3.attribute( "context" ); + if ((paramType == "Int") || (paramType == "UInt")) { + bool ok; + paramMax = e.attribute("max").toInt(&ok); + if (!ok) { + cerr << "Integer parameter must have a maximum (e.g. max=\"0\"): " + << dumpNode(e) << endl; + return 0; + } + } else if (paramType == "Enum") { + for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { + if (e2.tagName() == "values") { + for (QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement()) { + if (e3.tagName() == "value") { + paramValues.append(e3.text()); + } + } + break; + } + } + if (paramValues.isEmpty()) { + cerr << "No values specified for parameter '" << param + << "'." << endl; + return 0; + } + paramMax = paramValues.count() - 1; + } else { + cerr << "Parameter '" << param << "' has type " << paramType + << " but must be of type int, uint or Enum." << endl; + return 0; } - } - chlist.append( choice ); - } - } - choices = CfgEntry::Choices( chlist, name, prefix ); - } - else if ( tag == "emit" ) { - QDomNode signalNode; - Signal signal; - signal.name = e.attribute( "signal" ); - signalList.append( signal); - } - } - - - bool nameIsEmpty = name.isEmpty(); - if ( nameIsEmpty && key.isEmpty() ) { - cerr << "Entry must have a name or a key: " << dumpNode(element) << endl; - return 0; - } - - if ( key.isEmpty() ) { - key = name; - } - - if ( nameIsEmpty ) { - name = key; - name.remove( ' ' ); - } else if ( name.contains( ' ' ) ) { - cout<<"Entry '"<<name<<"' contains spaces! <name> elements can not contain spaces!"<<endl; - name.remove( ' ' ); - } - - if (name.contains("$(")) - { - if (param.isEmpty()) - { - cerr << "Name may not be parameterized: " << name << endl; - return 0; + } else if (tag == "default") { + if (e.attribute("param").isEmpty()) { + defaultValue = e.text(); + if (e.attribute("code") == "true") { + defaultCode = true; + } + } + } else if (tag == "choices") { + QString name = e.attribute("name"); + QString prefix = e.attribute("prefix"); + QList<CfgEntry::Choice> chlist; + for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { + if (e2.tagName() == "choice") { + CfgEntry::Choice choice; + choice.name = e2.attribute("name"); + if (choice.name.isEmpty()) { + cerr << "Tag <choice> requires attribute 'name'." << endl; + } + for (QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement()) { + if (e3.tagName() == "label") { + choice.label = e3.text(); + choice.context = e3.attribute("context"); + } + if (e3.tagName() == "tooltip") { + choice.toolTip = e3.text(); + choice.context = e3.attribute("context"); + } + if (e3.tagName() == "whatsthis") { + choice.whatsThis = e3.text(); + choice.context = e3.attribute("context"); + } + } + chlist.append(choice); + } + } + choices = CfgEntry::Choices(chlist, name, prefix); + } else if (tag == "emit") { + QDomNode signalNode; + Signal signal; + signal.name = e.attribute("signal"); + signalList.append(signal); + } } - } - else - { - if (!param.isEmpty()) - { - cerr << "Name must contain '$(" << param << ")': " << name << endl; - return 0; + + bool nameIsEmpty = name.isEmpty(); + if (nameIsEmpty && key.isEmpty()) { + cerr << "Entry must have a name or a key: " << dumpNode(element) << endl; + return 0; } - } - if ( label.isEmpty() ) { - label = key; - } + if (key.isEmpty()) { + key = name; + } - if ( type.isEmpty() ) type = "String"; // XXX : implicit type might be bad + if (nameIsEmpty) { + name = key; + name.remove(' '); + } else if (name.contains(' ')) { + cout << "Entry '" << name << "' contains spaces! <name> elements can not contain spaces!" << endl; + name.remove(' '); + } - if (!param.isEmpty()) - { - // Adjust name - paramName = name; - name.remove("$("+param+')'); - // Lookup defaults for indexed entries - for(int i = 0; i <= paramMax; i++) - { - paramDefaultValues.append(QString()); + if (name.contains("$(")) { + if (param.isEmpty()) { + cerr << "Name may not be parameterized: " << name << endl; + return 0; + } + } else { + if (!param.isEmpty()) { + cerr << "Name must contain '$(" << param << ")': " << name << endl; + return 0; + } } - for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) { - QString tag = e.tagName(); - if ( tag == "default" ) - { - QString index = e.attribute("param"); - if (index.isEmpty()) - continue; + if (label.isEmpty()) { + label = key; + } - bool ok; - int i = index.toInt(&ok); - if (!ok) - { - i = paramValues.indexOf(index); - if (i == -1) - { - cerr << "Index '" << index << "' for default value is unknown." << endl; - return 0; - } + if (type.isEmpty()) { + type = "String"; // XXX : implicit type might be bad + } + + if (!param.isEmpty()) { + // Adjust name + paramName = name; + name.remove("$(" + param + ')'); + // Lookup defaults for indexed entries + for (int i = 0; i <= paramMax; i++) { + paramDefaultValues.append(QString()); } - if ((i < 0) || (i > paramMax)) - { - cerr << "Index '" << i << "' for default value is out of range [0, "<< paramMax<<"]." << endl; - return 0; - } - - QString tmpDefaultValue = e.text(); - - if (e.attribute( "code" ) != "true") - preProcessDefault(tmpDefaultValue, name, type, choices, code, cfg); - - paramDefaultValues[i] = tmpDefaultValue; - } - } - } - - if (!validNameRegexp->exactMatch(name)) - { - if (nameIsEmpty) - cerr << "The key '" << key << "' can not be used as name for the entry because " - "it is not a valid name. You need to specify a valid name for this entry." << endl; - else - cerr << "The name '" << name << "' is not a valid name for an entry." << endl; - return 0; - } - - if (allNames.contains(name)) - { - if (nameIsEmpty) - cerr << "The key '" << key << "' can not be used as name for the entry because " - "it does not result in a unique name. You need to specify a unique name for this entry." << endl; - else - cerr << "The name '" << name << "' is not unique." << endl; - return 0; - } - allNames.append(name); - - if (!defaultCode) - { - preProcessDefault(defaultValue, name, type, choices, code, cfg); - } - - CfgEntry *result = new CfgEntry( group, type, key, name, labelContext, label, toolTipContext, toolTip, whatsThisContext, whatsThis, - code, defaultValue, choices, signalList, - hidden == "true" ); - if (!param.isEmpty()) - { - result->setParam(param); - result->setParamName(paramName); - result->setParamType(paramType); - result->setParamValues(paramValues); - result->setParamDefaultValues(paramDefaultValues); - result->setParamMax(paramMax); - } - result->setMinValue(minValue); - result->setMaxValue(maxValue); - - return result; + for (QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { + QString tag = e.tagName(); + if (tag == "default") { + QString index = e.attribute("param"); + if (index.isEmpty()) { + continue; + } + + bool ok; + int i = index.toInt(&ok); + if (!ok) { + i = paramValues.indexOf(index); + if (i == -1) { + cerr << "Index '" << index << "' for default value is unknown." << endl; + return 0; + } + } + + if ((i < 0) || (i > paramMax)) { + cerr << "Index '" << i << "' for default value is out of range [0, " << paramMax << "]." << endl; + return 0; + } + + QString tmpDefaultValue = e.text(); + + if (e.attribute("code") != "true") { + preProcessDefault(tmpDefaultValue, name, type, choices, code, cfg); + } + + paramDefaultValues[i] = tmpDefaultValue; + } + } + } + + if (!validNameRegexp->exactMatch(name)) { + if (nameIsEmpty) + cerr << "The key '" << key << "' can not be used as name for the entry because " + "it is not a valid name. You need to specify a valid name for this entry." << endl; + else { + cerr << "The name '" << name << "' is not a valid name for an entry." << endl; + } + return 0; + } + + if (allNames.contains(name)) { + if (nameIsEmpty) + cerr << "The key '" << key << "' can not be used as name for the entry because " + "it does not result in a unique name. You need to specify a unique name for this entry." << endl; + else { + cerr << "The name '" << name << "' is not unique." << endl; + } + return 0; + } + allNames.append(name); + + if (!defaultCode) { + preProcessDefault(defaultValue, name, type, choices, code, cfg); + } + + CfgEntry *result = new CfgEntry(group, type, key, name, labelContext, label, toolTipContext, toolTip, whatsThisContext, whatsThis, + code, defaultValue, choices, signalList, + hidden == "true"); + if (!param.isEmpty()) { + result->setParam(param); + result->setParamName(paramName); + result->setParamType(paramType); + result->setParamValues(paramValues); + result->setParamDefaultValues(paramDefaultValues); + result->setParamMax(paramMax); + } + result->setMinValue(minValue); + result->setMaxValue(maxValue); + + return result; } -static bool isUnsigned(const QString& type) +static bool isUnsigned(const QString &type) { - if ( type == "UInt" ) return true; - if ( type == "ULongLong" ) return true; + if (type == "UInt") { + return true; + } + if (type == "ULongLong") { + return true; + } return false; } /** Return parameter declaration for given type. */ -QString param( const QString &t ) +QString param(const QString &t) { const QString type = t.toLower(); - if ( type == "string" ) return "const QString &"; - else if ( type == "stringlist" ) return "const QStringList &"; - else if ( type == "font" ) return "const QFont &"; - else if ( type == "rect" ) return "const QRect &"; - else if ( type == "size" ) return "const QSize &"; - else if ( type == "color" ) return "const QColor &"; - else if ( type == "point" ) return "const QPoint &"; - else if ( type == "int" ) return "int"; - else if ( type == "uint" ) return "uint"; - else if ( type == "bool" ) return "bool"; - else if ( type == "double" ) return "double"; - else if ( type == "datetime" ) return "const QDateTime &"; - else if ( type == "longlong" ) return "qint64"; - else if ( type == "ulonglong" ) return "quint64"; - else if ( type == "intlist" ) return "const QList<int> &"; - else if ( type == "enum" ) return "int"; - else if ( type == "path" ) return "const QString &"; - else if ( type == "pathlist" ) return "const QStringList &"; - else if ( type == "password" ) return "const QString &"; - else if ( type == "url" ) return "const QUrl &"; - else if ( type == "urllist" ) return "const QList<QUrl> &"; - else { - cerr <<"kconfig_compiler does not support type \""<< type <<"\""<<endl; + if (type == "string") { + return "const QString &"; + } else if (type == "stringlist") { + return "const QStringList &"; + } else if (type == "font") { + return "const QFont &"; + } else if (type == "rect") { + return "const QRect &"; + } else if (type == "size") { + return "const QSize &"; + } else if (type == "color") { + return "const QColor &"; + } else if (type == "point") { + return "const QPoint &"; + } else if (type == "int") { + return "int"; + } else if (type == "uint") { + return "uint"; + } else if (type == "bool") { + return "bool"; + } else if (type == "double") { + return "double"; + } else if (type == "datetime") { + return "const QDateTime &"; + } else if (type == "longlong") { + return "qint64"; + } else if (type == "ulonglong") { + return "quint64"; + } else if (type == "intlist") { + return "const QList<int> &"; + } else if (type == "enum") { + return "int"; + } else if (type == "path") { + return "const QString &"; + } else if (type == "pathlist") { + return "const QStringList &"; + } else if (type == "password") { + return "const QString &"; + } else if (type == "url") { + return "const QUrl &"; + } else if (type == "urllist") { + return "const QList<QUrl> &"; + } else { + cerr << "kconfig_compiler does not support type \"" << type << "\"" << endl; return "QString"; //For now, but an assert would be better } } @@ -934,87 +1081,130 @@ QString param( const QString &t ) /** Actual C++ storage type for given type. */ -QString cppType( const QString &t ) +QString cppType(const QString &t) { const QString type = t.toLower(); - if ( type == "string" ) return "QString"; - else if ( type == "stringlist" ) return "QStringList"; - else if ( type == "font" ) return "QFont"; - else if ( type == "rect" ) return "QRect"; - else if ( type == "size" ) return "QSize"; - else if ( type == "color" ) return "QColor"; - else if ( type == "point" ) return "QPoint"; - else if ( type == "int" ) return "int"; - else if ( type == "uint" ) return "uint"; - else if ( type == "bool" ) return "bool"; - else if ( type == "double" ) return "double"; - else if ( type == "datetime" ) return "QDateTime"; - else if ( type == "longlong" ) return "qint64"; - else if ( type == "ulonglong" ) return "quint64"; - else if ( type == "intlist" ) return "QList<int>"; - else if ( type == "enum" ) return "int"; - else if ( type == "path" ) return "QString"; - else if ( type == "pathlist" ) return "QStringList"; - else if ( type == "password" ) return "QString"; - else if ( type == "url" ) return "QUrl"; - else if ( type == "urllist" ) return "QList<QUrl>"; - else { - cerr<<"kconfig_compiler does not support type \""<< type <<"\""<<endl; + if (type == "string") { + return "QString"; + } else if (type == "stringlist") { + return "QStringList"; + } else if (type == "font") { + return "QFont"; + } else if (type == "rect") { + return "QRect"; + } else if (type == "size") { + return "QSize"; + } else if (type == "color") { + return "QColor"; + } else if (type == "point") { + return "QPoint"; + } else if (type == "int") { + return "int"; + } else if (type == "uint") { + return "uint"; + } else if (type == "bool") { + return "bool"; + } else if (type == "double") { + return "double"; + } else if (type == "datetime") { + return "QDateTime"; + } else if (type == "longlong") { + return "qint64"; + } else if (type == "ulonglong") { + return "quint64"; + } else if (type == "intlist") { + return "QList<int>"; + } else if (type == "enum") { + return "int"; + } else if (type == "path") { + return "QString"; + } else if (type == "pathlist") { + return "QStringList"; + } else if (type == "password") { + return "QString"; + } else if (type == "url") { + return "QUrl"; + } else if (type == "urllist") { + return "QList<QUrl>"; + } else { + cerr << "kconfig_compiler does not support type \"" << type << "\"" << endl; return "QString"; //For now, but an assert would be better } } -QString defaultValue( const QString &t ) +QString defaultValue(const QString &t) { const QString type = t.toLower(); - if ( type == "string" ) return "\"\""; // Use empty string, not null string! - else if ( type == "stringlist" ) return "QStringList()"; - else if ( type == "font" ) return "QFont()"; - else if ( type == "rect" ) return "QRect()"; - else if ( type == "size" ) return "QSize()"; - else if ( type == "color" ) return "QColor(128, 128, 128)"; - else if ( type == "point" ) return "QPoint()"; - else if ( type == "int" ) return "0"; - else if ( type == "uint" ) return "0"; - else if ( type == "bool" ) return "false"; - else if ( type == "double" ) return "0.0"; - else if ( type == "datedime" ) return "QDateTime()"; - else if ( type == "longlong" ) return "0"; - else if ( type == "ulonglong" ) return "0"; - else if ( type == "intlist" ) return "QList<int>()"; - else if ( type == "enum" ) return "0"; - else if ( type == "path" ) return "\"\""; // Use empty string, not null string! - else if ( type == "pathlist" ) return "QStringList()"; - else if ( type == "password" ) return "\"\""; // Use empty string, not null string! - else if ( type == "url" ) return "QUrl()"; - else if ( type == "urllist" ) return "QList<QUrl>()"; - else { - cerr<<"Error, kconfig_compiler does not support the \""<< type <<"\" type!"<<endl; + if (type == "string") { + return "\"\""; // Use empty string, not null string! + } else if (type == "stringlist") { + return "QStringList()"; + } else if (type == "font") { + return "QFont()"; + } else if (type == "rect") { + return "QRect()"; + } else if (type == "size") { + return "QSize()"; + } else if (type == "color") { + return "QColor(128, 128, 128)"; + } else if (type == "point") { + return "QPoint()"; + } else if (type == "int") { + return "0"; + } else if (type == "uint") { + return "0"; + } else if (type == "bool") { + return "false"; + } else if (type == "double") { + return "0.0"; + } else if (type == "datedime") { + return "QDateTime()"; + } else if (type == "longlong") { + return "0"; + } else if (type == "ulonglong") { + return "0"; + } else if (type == "intlist") { + return "QList<int>()"; + } else if (type == "enum") { + return "0"; + } else if (type == "path") { + return "\"\""; // Use empty string, not null string! + } else if (type == "pathlist") { + return "QStringList()"; + } else if (type == "password") { + return "\"\""; // Use empty string, not null string! + } else if (type == "url") { + return "QUrl()"; + } else if (type == "urllist") { + return "QList<QUrl>()"; + } else { + cerr << "Error, kconfig_compiler does not support the \"" << type << "\" type!" << endl; return "QString"; //For now, but an assert would be better } } -QString itemType( const QString &type ) +QString itemType(const QString &type) { - QString t; + QString t; - t = type; - t.replace( 0, 1, t.left( 1 ).toUpper() ); + t = type; + t.replace(0, 1, t.left(1).toUpper()); - return t; + return t; } static QString itemDeclaration(const CfgEntry *e, const CfgConfig &cfg) { - if (cfg.itemAccessors) - return QString(); - - QString fCap = e->name(); - fCap[0] = fCap[0].toUpper(); - return " "+cfg.inherits+"::Item"+itemType( e->type() ) + - " *item" + fCap + - ( (!e->param().isEmpty())?(QString("[%1]").arg(e->paramMax()+1)) : QString()) + - ";\n"; + if (cfg.itemAccessors) { + return QString(); + } + + QString fCap = e->name(); + fCap[0] = fCap[0].toUpper(); + return " " + cfg.inherits + "::Item" + itemType(e->type()) + + " *item" + fCap + + ((!e->param().isEmpty()) ? (QString("[%1]").arg(e->paramMax() + 1)) : QString()) + + ";\n"; } // returns the name of an item variable @@ -1022,97 +1212,90 @@ static QString itemDeclaration(const CfgEntry *e, const CfgConfig &cfg) // like using d-> in case of dpointer static QString itemVar(const CfgEntry *e, const CfgConfig &cfg) { - QString result; - if (cfg.itemAccessors) - { - if ( !cfg.dpointer ) - { - result = 'm' + e->name() + "Item"; - result[1] = result[1].toUpper(); - } - else - { - result = e->name() + "Item"; - result[0] = result[0].toLower(); + QString result; + if (cfg.itemAccessors) { + if (!cfg.dpointer) { + result = 'm' + e->name() + "Item"; + result[1] = result[1].toUpper(); + } else { + result = e->name() + "Item"; + result[0] = result[0].toLower(); + } + } else { + result = "item" + e->name(); + result[4] = result[4].toUpper(); } - } - else - { - result = "item" + e->name(); - result[4] = result[4].toUpper(); - } - return result; + return result; } static QString itemPath(const CfgEntry *e, const CfgConfig &cfg) { - QString result; - if ( cfg.dpointer ) { - result = "d->"+itemVar(e, cfg); - } - else { - result = itemVar(e, cfg); - } - return result; + QString result; + if (cfg.dpointer) { + result = "d->" + itemVar(e, cfg); + } else { + result = itemVar(e, cfg); + } + return result; } -QString newItem( const QString &type, const QString &name, const QString &key, - const QString &defaultValue, const CfgConfig &cfg, const QString ¶m = QString()) +QString newItem(const QString &type, const QString &name, const QString &key, + const QString &defaultValue, const CfgConfig &cfg, const QString ¶m = QString()) { - QString t = "new "+cfg.inherits+"::Item" + itemType( type ) + - "( currentGroup(), " + key + ", " + varPath( name, cfg ) + param; - if ( type == "Enum" ) t += ", values" + name; - if ( !defaultValue.isEmpty() ) { - t += ", "; - if ( type == "String" ) t += defaultValue; - else t+= defaultValue; - } - t += " );"; - - return t; + QString t = "new " + cfg.inherits + "::Item" + itemType(type) + + "( currentGroup(), " + key + ", " + varPath(name, cfg) + param; + if (type == "Enum") { + t += ", values" + name; + } + if (!defaultValue.isEmpty()) { + t += ", "; + if (type == "String") { + t += defaultValue; + } else { + t += defaultValue; + } + } + t += " );"; + + return t; } QString paramString(const QString &s, const CfgEntry *e, int i) { - QString result = s; - QString needle = "$("+e->param()+')'; - if (result.contains(needle)) - { - QString tmp; - if (e->paramType() == "Enum") - { - tmp = e->paramValues()[i]; - } - else - { - tmp = QString::number(i); - } + QString result = s; + QString needle = "$(" + e->param() + ')'; + if (result.contains(needle)) { + QString tmp; + if (e->paramType() == "Enum") { + tmp = e->paramValues()[i]; + } else { + tmp = QString::number(i); + } - result.replace(needle, tmp); - } - return result; + result.replace(needle, tmp); + } + return result; } QString paramString(const QString &group, const QList<Param> ¶meters) { - QString paramString = group; - QString arguments; - int i = 1; - for (QList<Param>::ConstIterator it = parameters.constBegin(); - it != parameters.constEnd(); ++it) - { - if (paramString.contains("$("+(*it).name+')')) - { - QString tmp; - tmp.sprintf("%%%d", i++); - paramString.replace("$("+(*it).name+')', tmp); - arguments += ".arg( mParam"+(*it).name+" )"; - } - } - if (arguments.isEmpty()) - return "QLatin1String( \""+group+"\" )"; - - return "QString( QLatin1String( \""+paramString+"\" ) )"+arguments; + QString paramString = group; + QString arguments; + int i = 1; + for (QList<Param>::ConstIterator it = parameters.constBegin(); + it != parameters.constEnd(); ++it) { + if (paramString.contains("$(" + (*it).name + ')')) { + QString tmp; + tmp.sprintf("%%%d", i++); + paramString.replace("$(" + (*it).name + ')', tmp); + arguments += ".arg( mParam" + (*it).name + " )"; + } + } + if (arguments.isEmpty()) { + return "QLatin1String( \"" + group + "\" )"; + } + + return "QString( QLatin1String( \"" + paramString + "\" ) )" + arguments; } QString translatedString(const CfgConfig &cfg, const QString &string, const QString &context = QString(), const QString ¶m = QString(), const QString ¶mValue = QString()) @@ -1122,62 +1305,64 @@ QString translatedString(const CfgConfig &cfg, const QString &string, const QStr switch (cfg.translationSystem) { case CfgConfig::QtTranslation: if (!context.isEmpty()) { - result+= "/*: " + context + " */ QCoreApplication::translate(\""; + result += "/*: " + context + " */ QCoreApplication::translate(\""; } else { - result+= "QCoreApplication::translate(\""; + result += "QCoreApplication::translate(\""; } - result+= cfg.className + "\", "; + result += cfg.className + "\", "; break; case CfgConfig::KdeTranslation: if (!context.isEmpty()) { - result+= "i18nc(" + quoteString(context) + ", "; + result += "i18nc(" + quoteString(context) + ", "; } else { - result+= "i18n("; + result += "i18n("; } break; } if (!param.isEmpty()) { QString resolvedString = string; - resolvedString.replace("$("+param+')', paramValue); - result+= quoteString(resolvedString); + resolvedString.replace("$(" + param + ')', paramValue); + result += quoteString(resolvedString); } else { - result+= quoteString(string); + result += quoteString(string); } - result+= ')'; + result += ')'; return result; } /* int i is the value of the parameter */ -QString userTextsFunctions( CfgEntry *e, const CfgConfig &cfg, QString itemVarStr=QString(), QString i=QString() ) +QString userTextsFunctions(CfgEntry *e, const CfgConfig &cfg, QString itemVarStr = QString(), QString i = QString()) { - QString txt; - if (itemVarStr.isNull()) itemVarStr=itemPath(e, cfg); - if ( !e->label().isEmpty() ) { - txt += " " + itemVarStr + "->setLabel( "; - txt += translatedString(cfg, e->label(), e->labelContext(), e->param(), i); - txt += " );\n"; - } - if ( !e->toolTip().isEmpty() ) { - txt += " " + itemVarStr + "->setToolTip( "; - txt += translatedString(cfg, e->toolTip(), e->toolTipContext(), e->param(), i); - txt += " );\n"; - } - if ( !e->whatsThis().isEmpty() ) { - txt += " " + itemVarStr + "->setWhatsThis( "; - txt += translatedString(cfg, e->whatsThis(), e->whatsThisContext(), e->param(), i); - txt += " );\n"; - } - return txt; + QString txt; + if (itemVarStr.isNull()) { + itemVarStr = itemPath(e, cfg); + } + if (!e->label().isEmpty()) { + txt += " " + itemVarStr + "->setLabel( "; + txt += translatedString(cfg, e->label(), e->labelContext(), e->param(), i); + txt += " );\n"; + } + if (!e->toolTip().isEmpty()) { + txt += " " + itemVarStr + "->setToolTip( "; + txt += translatedString(cfg, e->toolTip(), e->toolTipContext(), e->param(), i); + txt += " );\n"; + } + if (!e->whatsThis().isEmpty()) { + txt += " " + itemVarStr + "->setWhatsThis( "; + txt += translatedString(cfg, e->whatsThis(), e->whatsThisContext(), e->param(), i); + txt += " );\n"; + } + return txt; } // returns the member accesor implementation // which should go in the h file if inline // or the cpp file if not inline -QString memberAccessorBody( CfgEntry *e, bool globalEnums, const CfgConfig &cfg ) +QString memberAccessorBody(CfgEntry *e, bool globalEnums, const CfgConfig &cfg) { QString result; QTextStream out(&result, QIODevice::WriteOnly); @@ -1186,13 +1371,16 @@ QString memberAccessorBody( CfgEntry *e, bool globalEnums, const CfgConfig &cfg bool useEnumType = cfg.useEnumTypes && t == "Enum"; out << "return "; - if (useEnumType) - out << "static_cast<" << enumType(e, globalEnums) << ">("; + if (useEnumType) { + out << "static_cast<" << enumType(e, globalEnums) << ">("; + } out << This << varPath(n, cfg); - if (!e->param().isEmpty()) - out << "[i]"; - if (useEnumType) - out << ")"; + if (!e->param().isEmpty()) { + out << "[i]"; + } + if (useEnumType) { + out << ")"; + } out << ";" << endl; return result; @@ -1201,113 +1389,110 @@ QString memberAccessorBody( CfgEntry *e, bool globalEnums, const CfgConfig &cfg // returns the member mutator implementation // which should go in the h file if inline // or the cpp file if not inline -QString memberMutatorBody( CfgEntry *e, const CfgConfig &cfg ) +QString memberMutatorBody(CfgEntry *e, const CfgConfig &cfg) { - QString result; - QTextStream out(&result, QIODevice::WriteOnly); - QString n = e->name(); - QString t = e->type(); - - if (!e->minValue().isEmpty()) - { - if (e->minValue() != "0" || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) - out << "if (v < " << e->minValue() << ")" << endl; - out << "{" << endl; - out << " qDebug() << \"" << setFunction(n); - out << ": value \" << v << \" is less than the minimum value of "; - out << e->minValue()<< "\";" << endl; - out << " v = " << e->minValue() << ";" << endl; - out << "}" << endl; - } - } - - if (!e->maxValue().isEmpty()) - { - out << endl << "if (v > " << e->maxValue() << ")" << endl; - out << "{" << endl; - out << " qDebug() << \"" << setFunction(n); - out << ": value \" << v << \" is greater than the maximum value of "; - out << e->maxValue()<< "\";" << endl; - out << " v = " << e->maxValue() << ";" << endl; - out << "}" << endl << endl; - } - - out << "if (!" << This << "isImmutable( QString::fromLatin1( \""; - if (!e->param().isEmpty()) - { - out << e->paramName().replace("$("+e->param()+")", "%1") << "\" ).arg( "; - if ( e->paramType() == "Enum" ) { - out << "QLatin1String( "; - - if (cfg.globalEnums) - out << enumName(e->param()) << "ToString[i]"; - else - out << enumName(e->param()) << "::enumToString[i]"; + QString result; + QTextStream out(&result, QIODevice::WriteOnly); + QString n = e->name(); + QString t = e->type(); + + if (!e->minValue().isEmpty()) { + if (e->minValue() != "0" || !isUnsigned(t)) { // skip writing "if uint<0" (#187579) + out << "if (v < " << e->minValue() << ")" << endl; + out << "{" << endl; + out << " qDebug() << \"" << setFunction(n); + out << ": value \" << v << \" is less than the minimum value of "; + out << e->minValue() << "\";" << endl; + out << " v = " << e->minValue() << ";" << endl; + out << "}" << endl; + } + } + + if (!e->maxValue().isEmpty()) { + out << endl << "if (v > " << e->maxValue() << ")" << endl; + out << "{" << endl; + out << " qDebug() << \"" << setFunction(n); + out << ": value \" << v << \" is greater than the maximum value of "; + out << e->maxValue() << "\";" << endl; + out << " v = " << e->maxValue() << ";" << endl; + out << "}" << endl << endl; + } + + out << "if (!" << This << "isImmutable( QString::fromLatin1( \""; + if (!e->param().isEmpty()) { + out << e->paramName().replace("$(" + e->param() + ")", "%1") << "\" ).arg( "; + if (e->paramType() == "Enum") { + out << "QLatin1String( "; + if (cfg.globalEnums) { + out << enumName(e->param()) << "ToString[i]"; + } else { + out << enumName(e->param()) << "::enumToString[i]"; + } + + out << " )"; + } else { + out << "i"; + } out << " )"; + } else { + out << n << "\" )"; } - else - { - out << "i"; - } - out << " )"; - } - else - { - out << n << "\" )"; - } - out << " ))" << (!e->signalList().empty() ? " {" : "") << endl; - out << " " << This << varPath(n, cfg); - if (!e->param().isEmpty()) - out << "[i]"; - out << " = v;" << endl; - - if ( !e->signalList().empty() ) { - Q_FOREACH(const Signal &signal, e->signalList()) { - out << " " << This << varPath("settingsChanged", cfg) << " |= " << signalEnumName(signal.name) << ";" << endl; - } - out << "}" << endl; - } - - return result; + out << " ))" << (!e->signalList().empty() ? " {" : "") << endl; + out << " " << This << varPath(n, cfg); + if (!e->param().isEmpty()) { + out << "[i]"; + } + out << " = v;" << endl; + + if (!e->signalList().empty()) { + Q_FOREACH (const Signal &signal, e->signalList()) { + out << " " << This << varPath("settingsChanged", cfg) << " |= " << signalEnumName(signal.name) << ";" << endl; + } + out << "}" << endl; + } + + return result; } // returns the member get default implementation // which should go in the h file if inline // or the cpp file if not inline -QString memberGetDefaultBody( CfgEntry *e ) +QString memberGetDefaultBody(CfgEntry *e) { - QString result = e->code(); - QTextStream out(&result, QIODevice::WriteOnly); - out << endl; - - if (!e->param().isEmpty()) { - out << " switch (i) {" << endl; - for (int i = 0; i <= e->paramMax(); ++i) { - if (!e->paramDefaultValue(i).isEmpty()) { - out << " case " << i << ": return " << e->paramDefaultValue(i) << ';' << endl; - } - } - out << " default:" << endl; - out << " return " << e->defaultValue().replace("$("+e->param()+')', "i") << ';' << endl; - out << " }" << endl; - } else { - out << " return " << e->defaultValue() << ';'; - } - - return result; + QString result = e->code(); + QTextStream out(&result, QIODevice::WriteOnly); + out << endl; + + if (!e->param().isEmpty()) { + out << " switch (i) {" << endl; + for (int i = 0; i <= e->paramMax(); ++i) { + if (!e->paramDefaultValue(i).isEmpty()) { + out << " case " << i << ": return " << e->paramDefaultValue(i) << ';' << endl; + } + } + out << " default:" << endl; + out << " return " << e->defaultValue().replace("$(" + e->param() + ')', "i") << ';' << endl; + out << " }" << endl; + } else { + out << " return " << e->defaultValue() << ';'; + } + + return result; } // returns the item accesor implementation // which should go in the h file if inline // or the cpp file if not inline -QString itemAccessorBody( CfgEntry *e, const CfgConfig &cfg ) +QString itemAccessorBody(CfgEntry *e, const CfgConfig &cfg) { QString result; QTextStream out(&result, QIODevice::WriteOnly); out << "return " << itemPath(e, cfg); - if (!e->param().isEmpty()) out << "[i]"; + if (!e->param().isEmpty()) { + out << "[i]"; + } out << ";" << endl; return result; @@ -1320,13 +1505,13 @@ QString indent(QString text, int spaces) QTextStream out(&result, QIODevice::WriteOnly); QTextStream in(&text, QIODevice::ReadOnly); QString currLine; - while ( !in.atEnd() ) - { - currLine = in.readLine(); - if (!currLine.isEmpty()) - for (int i=0; i < spaces; i++) - out << " "; - out << currLine << endl; + while (!in.atEnd()) { + currLine = in.readLine(); + if (!currLine.isEmpty()) + for (int i = 0; i < spaces; i++) { + out << " "; + } + out << currLine << endl; } return result; } @@ -1335,1004 +1520,1040 @@ QString indent(QString text, int spaces) // there are namespaces in p_ns void beginNamespaces(const QString &p_ns, QTextStream &p_out) { - if ( !p_ns.isEmpty() ) { - const QStringList nameSpaces = p_ns.split( "::" ); - foreach (const QString &ns, nameSpaces ) - p_out << "namespace " << ns << " {" << endl; - p_out << endl; - } + if (!p_ns.isEmpty()) { + const QStringList nameSpaces = p_ns.split("::"); + foreach (const QString &ns, nameSpaces) { + p_out << "namespace " << ns << " {" << endl; + } + p_out << endl; + } } // adds as many '}' lines to p_out as // there are namespaces in p_ns void endNamespaces(const QString &p_ns, QTextStream &p_out) { - if ( !p_ns.isEmpty() ) { - const int namespaceCount = p_ns.count( "::" ) + 1; - for ( int i = 0; i < namespaceCount; ++i ) - p_out << "}" << endl; - p_out << endl; - } + if (!p_ns.isEmpty()) { + const int namespaceCount = p_ns.count("::") + 1; + for (int i = 0; i < namespaceCount; ++i) { + p_out << "}" << endl; + } + p_out << endl; + } } - -int main( int argc, char **argv ) +int main(int argc, char **argv) { - QCoreApplication app(argc, argv); + QCoreApplication app(argc, argv); - validNameRegexp = new QRegExp("[a-zA-Z_][a-zA-Z0-9_]*"); + validNameRegexp = new QRegExp("[a-zA-Z_][a-zA-Z0-9_]*"); - QString directoryName, inputFilename, codegenFilename; - parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename); + QString directoryName, inputFilename, codegenFilename; + parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename); - QString baseDir = directoryName; + QString baseDir = directoryName; #ifdef Q_OS_WIN - if (!baseDir.endsWith('/') && !baseDir.endsWith('\\')) + if (!baseDir.endsWith('/') && !baseDir.endsWith('\\')) #else - if (!baseDir.endsWith('/')) + if (!baseDir.endsWith('/')) #endif - baseDir.append("/"); - - if (!codegenFilename.endsWith(QLatin1String(".kcfgc"))) - { - cerr << "Codegen options file must have extension .kcfgc" << endl; - return 1; - } - QString baseName = QFileInfo(codegenFilename).fileName(); - baseName = baseName.left(baseName.length() - 6); - - CfgConfig cfg = CfgConfig( codegenFilename ); - - QFile input( inputFilename ); - - QDomDocument doc; - QString errorMsg; - int errorRow; - int errorCol; - if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) { - cerr << "Unable to load document." << endl; - cerr << "Parse error in " << inputFilename << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl; - return 1; - } - - QDomElement cfgElement = doc.documentElement(); - - if ( cfgElement.isNull() ) { - cerr << "No document in kcfg file" << endl; - return 1; - } - - QString cfgFileName; - bool cfgFileNameArg = false; - QList<Param> parameters; - QList<Signal> signalList; - QStringList includes; - bool hasSignals = false; - - QList<CfgEntry*> entries; - - for ( QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) { - QString tag = e.tagName(); - - if ( tag == "include" ) { - QString includeFile = e.text(); - if (!includeFile.isEmpty()) - includes.append(includeFile); - - } else if ( tag == "kcfgfile" ) { - cfgFileName = e.attribute( "name" ); - cfgFileNameArg = e.attribute( "arg" ).toLower() == "true"; - for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) { - if ( e2.tagName() == "parameter" ) { - Param p; - p.name = e2.attribute( "name" ); - p.type = e2.attribute( "type" ); - if (p.type.isEmpty()) - p.type = "String"; - parameters.append( p ); - } - } - - } else if ( tag == "group" ) { - QString group = e.attribute( "name" ); - if ( group.isEmpty() ) { - cerr << "Group without name" << endl; + baseDir.append("/"); + + if (!codegenFilename.endsWith(QLatin1String(".kcfgc"))) { + cerr << "Codegen options file must have extension .kcfgc" << endl; return 1; - } - for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) { - if ( e2.tagName() != "entry" ) continue; - CfgEntry *entry = parseEntry( group, e2, cfg ); - if ( entry ) entries.append( entry ); - else { - cerr << "Can not parse entry." << endl; - return 1; + } + QString baseName = QFileInfo(codegenFilename).fileName(); + baseName = baseName.left(baseName.length() - 6); + + CfgConfig cfg = CfgConfig(codegenFilename); + + QFile input(inputFilename); + + QDomDocument doc; + QString errorMsg; + int errorRow; + int errorCol; + if (!doc.setContent(&input, &errorMsg, &errorRow, &errorCol)) { + cerr << "Unable to load document." << endl; + cerr << "Parse error in " << inputFilename << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl; + return 1; + } + + QDomElement cfgElement = doc.documentElement(); + + if (cfgElement.isNull()) { + cerr << "No document in kcfg file" << endl; + return 1; + } + + QString cfgFileName; + bool cfgFileNameArg = false; + QList<Param> parameters; + QList<Signal> signalList; + QStringList includes; + bool hasSignals = false; + + QList<CfgEntry *> entries; + + for (QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { + QString tag = e.tagName(); + + if (tag == "include") { + QString includeFile = e.text(); + if (!includeFile.isEmpty()) { + includes.append(includeFile); + } + + } else if (tag == "kcfgfile") { + cfgFileName = e.attribute("name"); + cfgFileNameArg = e.attribute("arg").toLower() == "true"; + for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { + if (e2.tagName() == "parameter") { + Param p; + p.name = e2.attribute("name"); + p.type = e2.attribute("type"); + if (p.type.isEmpty()) { + p.type = "String"; + } + parameters.append(p); + } + } + + } else if (tag == "group") { + QString group = e.attribute("name"); + if (group.isEmpty()) { + cerr << "Group without name" << endl; + return 1; + } + for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { + if (e2.tagName() != "entry") { + continue; + } + CfgEntry *entry = parseEntry(group, e2, cfg); + if (entry) { + entries.append(entry); + } else { + cerr << "Can not parse entry." << endl; + return 1; + } + } + } else if (tag == "signal") { + QString signalName = e.attribute("name"); + if (signalName.isEmpty()) { + cerr << "Signal without name." << endl; + return 1; + } + Signal theSignal; + theSignal.name = signalName; + + for (QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement()) { + if (e2.tagName() == "argument") { + SignalArguments argument; + argument.type = e2.attribute("type"); + if (argument.type.isEmpty()) { + cerr << "Signal argument without type." << endl; + return 1; + } + argument.variableName = e2.text(); + theSignal.arguments.append(argument); + } else if (e2.tagName() == "label") { + theSignal.label = e2.text(); + } + } + signalList.append(theSignal); } - } } - else if ( tag == "signal" ) { - QString signalName = e.attribute( "name" ); - if ( signalName.isEmpty() ) { - cerr << "Signal without name." << endl; + + if (cfg.className.isEmpty()) { + cerr << "Class name missing" << endl; return 1; - } - Signal theSignal; - theSignal.name = signalName; - - for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) { - if ( e2.tagName() == "argument") { - SignalArguments argument; - argument.type = e2.attribute("type"); - if ( argument.type.isEmpty() ) { - cerr << "Signal argument without type." << endl; - return 1; - } - argument.variableName = e2.text(); - theSignal.arguments.append(argument); - } - else if( e2.tagName() == "label") { - theSignal.label = e2.text(); - } - } - signalList.append(theSignal); - } - } - - if ( cfg.className.isEmpty() ) { - cerr << "Class name missing" << endl; - return 1; - } - - if ( cfg.singleton && !parameters.isEmpty() ) { - cerr << "Singleton class can not have parameters" << endl; - return 1; - } - - if ( !cfgFileName.isEmpty() && cfgFileNameArg) - { - cerr << "Having both a fixed filename and a filename as argument is not possible." << endl; - return 1; - } - - if ( entries.isEmpty() ) { - cerr << "No entries." << endl; - } + } + + if (cfg.singleton && !parameters.isEmpty()) { + cerr << "Singleton class can not have parameters" << endl; + return 1; + } + + if (!cfgFileName.isEmpty() && cfgFileNameArg) { + cerr << "Having both a fixed filename and a filename as argument is not possible." << endl; + return 1; + } + + if (entries.isEmpty()) { + cerr << "No entries." << endl; + } #if 0 - CfgEntry *cfg; - for( cfg = entries.first(); cfg; cfg = entries.next() ) { - cfg->dump(); - } + CfgEntry *cfg; + for (cfg = entries.first(); cfg; cfg = entries.next()) { + cfg->dump(); + } #endif - hasSignals = !signalList.empty(); - QString headerFileName = baseName + ".h"; - QString implementationFileName = baseName + ".cpp"; - QString mocFileName = baseName + ".moc"; - QString cppPreamble; // code to be inserted at the beginnin of the cpp file, e.g. initialization of static values - - QFile header( baseDir + headerFileName ); - if ( !header.open( QIODevice::WriteOnly ) ) { - cerr << "Can not open '" << baseDir << headerFileName << "for writing." << endl; - return 1; - } - - QTextStream h( &header ); - - h << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl; - h << "// All changes you do to this file will be lost." << endl; - - h << "#ifndef " << ( !cfg.nameSpace.isEmpty() ? QString (QString(cfg.nameSpace).replace( "::", "_" ).toUpper() + '_') : "" ) - << cfg.className.toUpper() << "_H" << endl; - h << "#define " << ( !cfg.nameSpace.isEmpty() ? QString (QString(cfg.nameSpace).replace( "::", "_" ).toUpper() + '_') : "" ) - << cfg.className.toUpper() << "_H" << endl << endl; - - // Includes - QStringList::ConstIterator it; - for( it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it ) { - if ( (*it).startsWith('"') ) - h << "#include " << *it << endl; - else - h << "#include <" << *it << ">" << endl; - } - - if ( cfg.headerIncludes.count() > 0 ) h << endl; - - if ( !cfg.singleton && parameters.isEmpty() ) - h << "#include <qglobal.h>" << endl; - - if ( cfg.inherits=="KCoreConfigSkeleton" ) { - h << "#include <kcoreconfigskeleton.h>" << endl; - } else { - h << "#include <kconfigskeleton.h>" << endl; - } - - h << "#include <QCoreApplication>" << endl; - h << "#include <QDebug>" << endl << endl; - - // Includes - for( it = includes.constBegin(); it != includes.constEnd(); ++it ) { - if ( (*it).startsWith('"') ) - h << "#include " << *it << endl; - else - h << "#include <" << *it << ">" << endl; - } - - beginNamespaces(cfg.nameSpace, h); - - // Private class declaration - if ( cfg.dpointer ) - h << "class " << cfg.className << "Private;" << endl << endl; - - // Class declaration header - h << "class " << cfg.visibility << cfg.className << " : public " << cfg.inherits << endl; - - h << "{" << endl; - // Add Q_OBJECT macro if the config need signals. - if( hasSignals ) - h << " Q_OBJECT" << endl; - h << " public:" << endl; - - // enums - QList<CfgEntry*>::ConstIterator itEntry; - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - const CfgEntry::Choices &choices = (*itEntry)->choices(); - const QList<CfgEntry::Choice> chlist = choices.choices; - if ( !chlist.isEmpty() ) { - QStringList values; - QList<CfgEntry::Choice>::ConstIterator itChoice; - for( itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice ) { - values.append( choices.prefix + (*itChoice).name ); - } - if ( choices.name().isEmpty() ) { - if ( cfg.globalEnums ) { - h << " enum " << enumName( (*itEntry)->name(), (*itEntry)->choices() ) << " { " << values.join( ", " ) << " };" << endl; + hasSignals = !signalList.empty(); + QString headerFileName = baseName + ".h"; + QString implementationFileName = baseName + ".cpp"; + QString mocFileName = baseName + ".moc"; + QString cppPreamble; // code to be inserted at the beginnin of the cpp file, e.g. initialization of static values + + QFile header(baseDir + headerFileName); + if (!header.open(QIODevice::WriteOnly)) { + cerr << "Can not open '" << baseDir << headerFileName << "for writing." << endl; + return 1; + } + + QTextStream h(&header); + + h << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl; + h << "// All changes you do to this file will be lost." << endl; + + h << "#ifndef " << (!cfg.nameSpace.isEmpty() ? QString(QString(cfg.nameSpace).replace("::", "_").toUpper() + '_') : "") + << cfg.className.toUpper() << "_H" << endl; + h << "#define " << (!cfg.nameSpace.isEmpty() ? QString(QString(cfg.nameSpace).replace("::", "_").toUpper() + '_') : "") + << cfg.className.toUpper() << "_H" << endl << endl; + + // Includes + QStringList::ConstIterator it; + for (it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it) { + if ((*it).startsWith('"')) { + h << "#include " << *it << endl; } else { - // Create an automatically named enum - h << " class " << enumName( (*itEntry)->name(), (*itEntry)->choices() ) << endl; - h << " {" << endl; - h << " public:" << endl; - h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl; - h << " };" << endl; - } - } else if ( !choices.external() ) { - // Create a named enum - h << " enum " << enumName( (*itEntry)->name(), (*itEntry)->choices() ) << " { " << values.join( ", " ) << " };" << endl; - } - } - const QStringList values = (*itEntry)->paramValues(); - if ( !values.isEmpty() ) { - if ( cfg.globalEnums ) { - // ### FIXME!! - // make the following string table an index-based string search! - // ### - h << " enum " << enumName( (*itEntry)->param() ) << " { " << values.join( ", " ) << " };" << endl; - h << " static const char* const " << enumName( (*itEntry)->param() ) << "ToString[];" << endl; - cppPreamble += "const char* const " + cfg.className + "::" + enumName( (*itEntry)->param() ) + - "ToString[] = { \"" + values.join( "\", \"" ) + "\" };\n"; - } else { - h << " class " << enumName( (*itEntry)->param() ) << endl; - h << " {" << endl; - h << " public:" << endl; - h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl; - h << " static const char* const enumToString[];" << endl; - h << " };" << endl; - cppPreamble += "const char* const " + cfg.className + "::" + enumName( (*itEntry)->param() ) + - "::enumToString[] = { \"" + values.join( "\", \"" ) + "\" };\n"; - } - } - } - if ( hasSignals ) { - h << "\n enum {" << endl; - unsigned val = 1; - QList<Signal>::ConstIterator it, itEnd = signalList.constEnd(); - for ( it = signalList.constBegin(); it != itEnd; val <<= 1) { - if ( !val ) { - cerr << "Too many signals to create unique bit masks" << endl; - exit(1); - } - Signal signal = *it; - h << " " << signalEnumName(signal.name) << " = 0x" << hex << val; - if ( ++it != itEnd ) - h << ","; - h << endl; - } - h << " };" << dec << endl; - } - h << endl; - // Constructor or singleton accessor - if ( !cfg.singleton ) { - h << " " << cfg.className << "("; - if (cfgFileNameArg) - { - if(cfg.forceStringFilename) - h << " const QString &cfgfilename" - << (parameters.isEmpty() ? " = QString()" : ", "); - else - h << " KSharedConfig::Ptr config" - << (parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", "); + h << "#include <" << *it << ">" << endl; + } } - for (QList<Param>::ConstIterator it = parameters.constBegin(); - it != parameters.constEnd(); ++it) - { - if (it != parameters.constBegin()) - h << ","; - h << " " << param((*it).type) << " " << (*it).name; - } - h << " );" << endl; - } else { - h << " static " << cfg.className << " *self();" << endl; - if (cfgFileNameArg) - { - h << " static void instance(const QString& cfgfilename);" << endl; + + if (cfg.headerIncludes.count() > 0) { + h << endl; } - } - // Destructor - h << " ~" << cfg.className << "();" << endl << endl; + if (!cfg.singleton && parameters.isEmpty()) { + h << "#include <qglobal.h>" << endl; + } - // global variables - if (cfg.staticAccessors) - This = "self()->"; - else - Const = " const"; + if (cfg.inherits == "KCoreConfigSkeleton") { + h << "#include <kcoreconfigskeleton.h>" << endl; + } else { + h << "#include <kconfigskeleton.h>" << endl; + } - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - QString n = (*itEntry)->name(); - QString t = (*itEntry)->type(); + h << "#include <QCoreApplication>" << endl; + h << "#include <QDebug>" << endl << endl; - // Manipulator - if (cfg.allMutators || cfg.mutators.contains(n)) - { - h << " /**" << endl; - h << " Set " << (*itEntry)->label() << endl; - h << " */" << endl; - if (cfg.staticAccessors) - h << " static" << endl; - h << " void " << setFunction(n) << "( "; - if (!(*itEntry)->param().isEmpty()) - h << cppType((*itEntry)->paramType()) << " i, "; - if (cfg.useEnumTypes && t == "Enum") - h << enumType(*itEntry, cfg.globalEnums); - else - h << param( t ); - h << " v )"; - // function body inline only if not using dpointer - // for BC mode - if ( !cfg.dpointer ) - { - h << endl << " {" << endl; - h << indent(memberMutatorBody(*itEntry, cfg), 6 ); - h << " }" << endl; - } - else - { - h << ";" << endl; - } - } - h << endl; - // Accessor - h << " /**" << endl; - h << " Get " << (*itEntry)->label() << endl; - h << " */" << endl; - if (cfg.staticAccessors) - h << " static" << endl; - h << " "; - if (cfg.useEnumTypes && t == "Enum") - h << enumType(*itEntry, cfg.globalEnums); - else - h << cppType(t); - h << " " << getFunction(n) << "("; - if (!(*itEntry)->param().isEmpty()) - h << " " << cppType((*itEntry)->paramType()) <<" i "; - h << ")" << Const; - // function body inline only if not using dpointer - // for BC mode - if ( !cfg.dpointer ) - { - h << endl << " {" << endl; - h << indent(memberAccessorBody(*itEntry, cfg.globalEnums, cfg), 6 ); - h << " }" << endl; + // Includes + for (it = includes.constBegin(); it != includes.constEnd(); ++it) { + if ((*it).startsWith('"')) { + h << "#include " << *it << endl; + } else { + h << "#include <" << *it << ">" << endl; + } } - else - { - h << ";" << endl; - } - - // Default value Accessor - if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) { - h << endl; - h << " /**" << endl; - h << " Get " << (*itEntry)->label() << " default value" << endl; - h << " */" << endl; - if (cfg.staticAccessors) - h << " static" << endl; - h << " "; - if (cfg.useEnumTypes && t == "Enum") - h << enumType(*itEntry, cfg.globalEnums); - else - h << cppType(t); - h << " " << getDefaultFunction(n) << "("; - if ( !(*itEntry)->param().isEmpty() ) - h << " " << cppType( (*itEntry)->paramType() ) <<" i "; - h << ")" << Const << endl; - h << " {" << endl; - h << " return "; - if (cfg.useEnumTypes && t == "Enum") - h << "static_cast<" << enumType(*itEntry, cfg.globalEnums) << ">("; - h << getDefaultFunction(n) << "_helper("; - if ( !(*itEntry)->param().isEmpty() ) - h << " i "; - h << ")"; - if (cfg.useEnumTypes && t == "Enum") - h << ")"; - h << ";" << endl; - h << " }" << endl; - } - - // Item accessor - if ( cfg.itemAccessors ) { - h << endl; - h << " /**" << endl; - h << " Get Item object corresponding to " << n << "()" - << endl; - h << " */" << endl; - h << " Item" << itemType( (*itEntry)->type() ) << " *" - << getFunction( n ) << "Item("; - if (!(*itEntry)->param().isEmpty()) { - h << " " << cppType((*itEntry)->paramType()) << " i "; - } - h << ")"; - if ( !cfg.dpointer ) - { - h << endl << " {" << endl; - h << indent( itemAccessorBody((*itEntry), cfg), 6); - h << " }" << endl; - } - else - { - h << ";" << endl; - } + + beginNamespaces(cfg.nameSpace, h); + + // Private class declaration + if (cfg.dpointer) { + h << "class " << cfg.className << "Private;" << endl << endl; } + // Class declaration header + h << "class " << cfg.visibility << cfg.className << " : public " << cfg.inherits << endl; + + h << "{" << endl; + // Add Q_OBJECT macro if the config need signals. + if (hasSignals) { + h << " Q_OBJECT" << endl; + } + h << " public:" << endl; + + // enums + QList<CfgEntry *>::ConstIterator itEntry; + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + const CfgEntry::Choices &choices = (*itEntry)->choices(); + const QList<CfgEntry::Choice> chlist = choices.choices; + if (!chlist.isEmpty()) { + QStringList values; + QList<CfgEntry::Choice>::ConstIterator itChoice; + for (itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice) { + values.append(choices.prefix + (*itChoice).name); + } + if (choices.name().isEmpty()) { + if (cfg.globalEnums) { + h << " enum " << enumName((*itEntry)->name(), (*itEntry)->choices()) << " { " << values.join(", ") << " };" << endl; + } else { + // Create an automatically named enum + h << " class " << enumName((*itEntry)->name(), (*itEntry)->choices()) << endl; + h << " {" << endl; + h << " public:" << endl; + h << " enum type { " << values.join(", ") << ", COUNT };" << endl; + h << " };" << endl; + } + } else if (!choices.external()) { + // Create a named enum + h << " enum " << enumName((*itEntry)->name(), (*itEntry)->choices()) << " { " << values.join(", ") << " };" << endl; + } + } + const QStringList values = (*itEntry)->paramValues(); + if (!values.isEmpty()) { + if (cfg.globalEnums) { + // ### FIXME!! + // make the following string table an index-based string search! + // ### + h << " enum " << enumName((*itEntry)->param()) << " { " << values.join(", ") << " };" << endl; + h << " static const char* const " << enumName((*itEntry)->param()) << "ToString[];" << endl; + cppPreamble += "const char* const " + cfg.className + "::" + enumName((*itEntry)->param()) + + "ToString[] = { \"" + values.join("\", \"") + "\" };\n"; + } else { + h << " class " << enumName((*itEntry)->param()) << endl; + h << " {" << endl; + h << " public:" << endl; + h << " enum type { " << values.join(", ") << ", COUNT };" << endl; + h << " static const char* const enumToString[];" << endl; + h << " };" << endl; + cppPreamble += "const char* const " + cfg.className + "::" + enumName((*itEntry)->param()) + + "::enumToString[] = { \"" + values.join("\", \"") + "\" };\n"; + } + } + } + if (hasSignals) { + h << "\n enum {" << endl; + unsigned val = 1; + QList<Signal>::ConstIterator it, itEnd = signalList.constEnd(); + for (it = signalList.constBegin(); it != itEnd; val <<= 1) { + if (!val) { + cerr << "Too many signals to create unique bit masks" << endl; + exit(1); + } + Signal signal = *it; + h << " " << signalEnumName(signal.name) << " = 0x" << hex << val; + if (++it != itEnd) { + h << ","; + } + h << endl; + } + h << " };" << dec << endl; + } h << endl; - } + // Constructor or singleton accessor + if (!cfg.singleton) { + h << " " << cfg.className << "("; + if (cfgFileNameArg) { + if (cfg.forceStringFilename) + h << " const QString &cfgfilename" + << (parameters.isEmpty() ? " = QString()" : ", "); + else + h << " KSharedConfig::Ptr config" + << (parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", "); + } + for (QList<Param>::ConstIterator it = parameters.constBegin(); + it != parameters.constEnd(); ++it) { + if (it != parameters.constBegin()) { + h << ","; + } + h << " " << param((*it).type) << " " << (*it).name; + } + h << " );" << endl; + } else { + h << " static " << cfg.className << " *self();" << endl; + if (cfgFileNameArg) { + h << " static void instance(const QString& cfgfilename);" << endl; + } + } + // Destructor + h << " ~" << cfg.className << "();" << endl << endl; - // Signal definition. - if( hasSignals ) { - h << endl; - h << " Q_SIGNALS:"; - Q_FOREACH(const Signal &signal, signalList) { - h << endl; - if ( !signal.label.isEmpty() ) { + // global variables + if (cfg.staticAccessors) { + This = "self()->"; + } else { + Const = " const"; + } + + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + QString n = (*itEntry)->name(); + QString t = (*itEntry)->type(); + + // Manipulator + if (cfg.allMutators || cfg.mutators.contains(n)) { + h << " /**" << endl; + h << " Set " << (*itEntry)->label() << endl; + h << " */" << endl; + if (cfg.staticAccessors) { + h << " static" << endl; + } + h << " void " << setFunction(n) << "( "; + if (!(*itEntry)->param().isEmpty()) { + h << cppType((*itEntry)->paramType()) << " i, "; + } + if (cfg.useEnumTypes && t == "Enum") { + h << enumType(*itEntry, cfg.globalEnums); + } else { + h << param(t); + } + h << " v )"; + // function body inline only if not using dpointer + // for BC mode + if (!cfg.dpointer) { + h << endl << " {" << endl; + h << indent(memberMutatorBody(*itEntry, cfg), 6); + h << " }" << endl; + } else { + h << ";" << endl; + } + } + h << endl; + // Accessor h << " /**" << endl; - h << " " << signal.label << endl; + h << " Get " << (*itEntry)->label() << endl; h << " */" << endl; - } - h << " void " << signal.name << "("; - QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); - for ( it = signal.arguments.constBegin(); it != itEnd; ) { - SignalArguments argument = *it; - QString type = param(argument.type); - if ( cfg.useEnumTypes && argument.type == "Enum" ) { - for ( int i = 0, end = entries.count(); i < end; ++i ) { - if ( entries[i]->name() == argument.variableName ) { - type = enumType(entries[i], cfg.globalEnums); - break; + if (cfg.staticAccessors) { + h << " static" << endl; + } + h << " "; + if (cfg.useEnumTypes && t == "Enum") { + h << enumType(*itEntry, cfg.globalEnums); + } else { + h << cppType(t); + } + h << " " << getFunction(n) << "("; + if (!(*itEntry)->param().isEmpty()) { + h << " " << cppType((*itEntry)->paramType()) << " i "; + } + h << ")" << Const; + // function body inline only if not using dpointer + // for BC mode + if (!cfg.dpointer) { + h << endl << " {" << endl; + h << indent(memberAccessorBody(*itEntry, cfg.globalEnums, cfg), 6); + h << " }" << endl; + } else { + h << ";" << endl; + } + + // Default value Accessor + if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) { + h << endl; + h << " /**" << endl; + h << " Get " << (*itEntry)->label() << " default value" << endl; + h << " */" << endl; + if (cfg.staticAccessors) { + h << " static" << endl; + } + h << " "; + if (cfg.useEnumTypes && t == "Enum") { + h << enumType(*itEntry, cfg.globalEnums); + } else { + h << cppType(t); + } + h << " " << getDefaultFunction(n) << "("; + if (!(*itEntry)->param().isEmpty()) { + h << " " << cppType((*itEntry)->paramType()) << " i "; + } + h << ")" << Const << endl; + h << " {" << endl; + h << " return "; + if (cfg.useEnumTypes && t == "Enum") { + h << "static_cast<" << enumType(*itEntry, cfg.globalEnums) << ">("; + } + h << getDefaultFunction(n) << "_helper("; + if (!(*itEntry)->param().isEmpty()) { + h << " i "; + } + h << ")"; + if (cfg.useEnumTypes && t == "Enum") { + h << ")"; } - } + h << ";" << endl; + h << " }" << endl; } - h << type << " " << argument.variableName; - if ( ++it != itEnd ) { - h << ", "; + + // Item accessor + if (cfg.itemAccessors) { + h << endl; + h << " /**" << endl; + h << " Get Item object corresponding to " << n << "()" + << endl; + h << " */" << endl; + h << " Item" << itemType((*itEntry)->type()) << " *" + << getFunction(n) << "Item("; + if (!(*itEntry)->param().isEmpty()) { + h << " " << cppType((*itEntry)->paramType()) << " i "; + } + h << ")"; + if (!cfg.dpointer) { + h << endl << " {" << endl; + h << indent(itemAccessorBody((*itEntry), cfg), 6); + h << " }" << endl; + } else { + h << ";" << endl; + } } - } - h << ");" << endl; + + h << endl; } - h << endl; - } - - h << " protected:" << endl; - - // Private constructor for singleton - if ( cfg.singleton ) { - h << " " << cfg.className << "("; - if ( cfgFileNameArg ) - h << "const QString& arg"; - h << ");" << endl; - h << " friend class " << cfg.className << "Helper;" << endl << endl; - } - - if ( hasSignals ) { - h << " virtual bool usrWriteConfig();" << endl; - } - - // Member variables - if ( !cfg.memberVariables.isEmpty() && cfg.memberVariables != "private" && cfg.memberVariables != "dpointer") { - h << " " << cfg.memberVariables << ":" << endl; - } - - // Class Parameters - for (QList<Param>::ConstIterator it = parameters.constBegin(); - it != parameters.constEnd(); ++it) - { - h << " " << cppType((*it).type) << " mParam" << (*it).name << ";" << endl; - } - - if ( cfg.memberVariables != "dpointer" ) - { - QString group; - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - if ( (*itEntry)->group() != group ) { - group = (*itEntry)->group(); + + // Signal definition. + if (hasSignals) { + h << endl; + h << " Q_SIGNALS:"; + Q_FOREACH (const Signal &signal, signalList) { + h << endl; + if (!signal.label.isEmpty()) { + h << " /**" << endl; + h << " " << signal.label << endl; + h << " */" << endl; + } + h << " void " << signal.name << "("; + QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); + for (it = signal.arguments.constBegin(); it != itEnd;) { + SignalArguments argument = *it; + QString type = param(argument.type); + if (cfg.useEnumTypes && argument.type == "Enum") { + for (int i = 0, end = entries.count(); i < end; ++i) { + if (entries[i]->name() == argument.variableName) { + type = enumType(entries[i], cfg.globalEnums); + break; + } + } + } + h << type << " " << argument.variableName; + if (++it != itEnd) { + h << ", "; + } + } + h << ");" << endl; + } h << endl; - h << " // " << group << endl; - } - h << " " << cppType( (*itEntry)->type() ) << " " << varName( (*itEntry)->name(), cfg ); - if ( !(*itEntry)->param().isEmpty() ) - { - h << QString("[%1]").arg( (*itEntry)->paramMax()+1 ); - } - h << ";" << endl; - - if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) ) - { - h << " "; - if (cfg.staticAccessors) - h << "static "; - h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; - if ( !(*itEntry)->param().isEmpty() ) - h << " " << cppType( (*itEntry)->paramType() ) <<" i "; - h << ")" << Const << ";" << endl; - } - } - - h << endl << " private:" << endl; - if ( cfg.itemAccessors ) { - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - h << " Item" << itemType( (*itEntry)->type() ) << " *" << itemVar( *itEntry, cfg ); - if ( !(*itEntry)->param().isEmpty() ) h << QString("[%1]").arg( (*itEntry)->paramMax()+1 ); - h << ";" << endl; - } - } - if ( hasSignals ) - h << " uint " << varName("settingsChanged", cfg) << ";" << endl; - - } - else - { - // use a private class for both member variables and items - h << " private:" << endl; - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) ) { - h << " "; - if (cfg.staticAccessors) - h << "static "; - h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; - if ( !(*itEntry)->param().isEmpty() ) - h << " " << cppType( (*itEntry)->paramType() ) <<" i "; - h << ")" << Const << ";" << endl; - } } - h << " " + cfg.className + "Private *d;" << endl; - } - if (cfg.customAddons) - { - h << " // Include custom additions" << endl; - h << " #include \"" << filenameOnly(baseName) << "_addons.h\"" <<endl; - } + h << " protected:" << endl; - h << "};" << endl << endl; + // Private constructor for singleton + if (cfg.singleton) { + h << " " << cfg.className << "("; + if (cfgFileNameArg) { + h << "const QString& arg"; + } + h << ");" << endl; + h << " friend class " << cfg.className << "Helper;" << endl << endl; + } - endNamespaces(cfg.nameSpace, h); + if (hasSignals) { + h << " virtual bool usrWriteConfig();" << endl; + } - h << "#endif" << endl << endl; + // Member variables + if (!cfg.memberVariables.isEmpty() && cfg.memberVariables != "private" && cfg.memberVariables != "dpointer") { + h << " " << cfg.memberVariables << ":" << endl; + } + // Class Parameters + for (QList<Param>::ConstIterator it = parameters.constBegin(); + it != parameters.constEnd(); ++it) { + h << " " << cppType((*it).type) << " mParam" << (*it).name << ";" << endl; + } - header.close(); + if (cfg.memberVariables != "dpointer") { + QString group; + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + if ((*itEntry)->group() != group) { + group = (*itEntry)->group(); + h << endl; + h << " // " << group << endl; + } + h << " " << cppType((*itEntry)->type()) << " " << varName((*itEntry)->name(), cfg); + if (!(*itEntry)->param().isEmpty()) { + h << QString("[%1]").arg((*itEntry)->paramMax() + 1); + } + h << ";" << endl; + + if (cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name())) { + h << " "; + if (cfg.staticAccessors) { + h << "static "; + } + h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; + if (!(*itEntry)->param().isEmpty()) { + h << " " << cppType((*itEntry)->paramType()) << " i "; + } + h << ")" << Const << ";" << endl; + } + } - QFile implementation( baseDir + implementationFileName ); - if ( !implementation.open( QIODevice::WriteOnly ) ) { - cerr << "Can not open '" << implementationFileName << "for writing." - << endl; - return 1; - } + h << endl << " private:" << endl; + if (cfg.itemAccessors) { + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + h << " Item" << itemType((*itEntry)->type()) << " *" << itemVar(*itEntry, cfg); + if (!(*itEntry)->param().isEmpty()) { + h << QString("[%1]").arg((*itEntry)->paramMax() + 1); + } + h << ";" << endl; + } + } + if (hasSignals) { + h << " uint " << varName("settingsChanged", cfg) << ";" << endl; + } - QTextStream cpp( &implementation ); + } else { + // use a private class for both member variables and items + h << " private:" << endl; + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + if (cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name())) { + h << " "; + if (cfg.staticAccessors) { + h << "static "; + } + h << cppType((*itEntry)->type()) << " " << getDefaultFunction((*itEntry)->name()) << "_helper("; + if (!(*itEntry)->param().isEmpty()) { + h << " " << cppType((*itEntry)->paramType()) << " i "; + } + h << ")" << Const << ";" << endl; + } + } + h << " " + cfg.className + "Private *d;" << endl; + } + if (cfg.customAddons) { + h << " // Include custom additions" << endl; + h << " #include \"" << filenameOnly(baseName) << "_addons.h\"" << endl; + } - cpp << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl; - cpp << "// All changes you do to this file will be lost." << endl << endl; + h << "};" << endl << endl; - cpp << "#include \"" << headerFileName << "\"" << endl << endl; + endNamespaces(cfg.nameSpace, h); - for( it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it ) { - if ( (*it).startsWith('"') ) - cpp << "#include " << *it << endl; - else - cpp << "#include <" << *it << ">" << endl; - } + h << "#endif" << endl << endl; - if ( cfg.sourceIncludes.count() > 0 ) cpp << endl; + header.close(); - if ( cfg.setUserTexts && cfg.translationSystem==CfgConfig::KdeTranslation) - cpp << "#include <klocalizedstring.h>" << endl << endl; + QFile implementation(baseDir + implementationFileName); + if (!implementation.open(QIODevice::WriteOnly)) { + cerr << "Can not open '" << implementationFileName << "for writing." + << endl; + return 1; + } - // Header required by singleton implementation - if ( cfg.singleton ) - cpp << "#include <qglobal.h>" << endl << "#include <QtCore/QFile>" << endl << endl; - if ( cfg.singleton && cfgFileNameArg ) - cpp << "#include <QDebug>" << endl << endl; + QTextStream cpp(&implementation); - if ( !cfg.nameSpace.isEmpty() ) - cpp << "using namespace " << cfg.nameSpace << ";" << endl << endl; + cpp << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl; + cpp << "// All changes you do to this file will be lost." << endl << endl; - QString group; + cpp << "#include \"" << headerFileName << "\"" << endl << endl; - // private class implementation - if ( cfg.dpointer ) - { - beginNamespaces(cfg.nameSpace, cpp); - cpp << "class " << cfg.className << "Private" << endl; - cpp << "{" << endl; - cpp << " public:" << endl; - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - if ( (*itEntry)->group() != group ) { - group = (*itEntry)->group(); + for (it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it) { + if ((*it).startsWith('"')) { + cpp << "#include " << *it << endl; + } else { + cpp << "#include <" << *it << ">" << endl; + } + } + + if (cfg.sourceIncludes.count() > 0) { cpp << endl; - cpp << " // " << group << endl; - } - cpp << " " << cppType( (*itEntry)->type() ) << " " << varName( (*itEntry)->name(), cfg ); - if ( !(*itEntry)->param().isEmpty() ) - { - cpp << QString("[%1]").arg( (*itEntry)->paramMax()+1 ); - } - cpp << ";" << endl; - } - cpp << endl << " // items" << endl; - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - cpp << " "+cfg.inherits+"::Item" << itemType( (*itEntry)->type() ) << " *" << itemVar( *itEntry, cfg ); - if ( !(*itEntry)->param().isEmpty() ) cpp << QString("[%1]").arg( (*itEntry)->paramMax()+1 ); - cpp << ";" << endl; - } - if ( hasSignals ) { - cpp << " uint " << varName("settingsChanged", cfg) << ";" << endl; - } - - cpp << "};" << endl << endl; - endNamespaces(cfg.nameSpace, cpp); - } - - // Singleton implementation - if ( cfg.singleton ) { - beginNamespaces(cfg.nameSpace, cpp); - cpp << "class " << cfg.className << "Helper" << endl; - cpp << '{' << endl; - cpp << " public:" << endl; - cpp << " " << cfg.className << "Helper() : q(0) {}" << endl; - cpp << " ~" << cfg.className << "Helper() { delete q; }" << endl; - cpp << " " << cfg.className << " *q;" << endl; - cpp << "};" << endl; - endNamespaces(cfg.nameSpace, cpp); - cpp << "Q_GLOBAL_STATIC(" << cfg.className << "Helper, s_global" << cfg.className << ")" << endl; - - cpp << cfg.className << " *" << cfg.className << "::self()" << endl; - cpp << "{" << endl; - if ( cfgFileNameArg ) { - cpp << " if (!s_global" << cfg.className << "()->q)" << endl; - cpp << " qFatal(\"you need to call " << cfg.className << "::instance before using\");" << endl; - } else { - cpp << " if (!s_global" << cfg.className << "()->q) {" << endl; - cpp << " new " << cfg.className << ';' << endl; - cpp << " s_global" << cfg.className << "()->q->readConfig();" << endl; - cpp << " }" << endl << endl; } - cpp << " return s_global" << cfg.className << "()->q;" << endl; - cpp << "}" << endl << endl; - if ( cfgFileNameArg ) { - cpp << "void " << cfg.className << "::instance(const QString& cfgfilename)" << endl; - cpp << "{" << endl; - cpp << " if (s_global" << cfg.className << "()->q) {" << endl; - cpp << " qDebug() << \"" << cfg.className << "::instance called after the first use - ignoring\";" << endl; - cpp << " return;" << endl; - cpp << " }" << endl; - cpp << " new " << cfg.className << "(cfgfilename);" << endl; - cpp << " s_global" << cfg.className << "()->q->readConfig();" << endl; - cpp << "}" << endl << endl; - } - } - - if ( !cppPreamble.isEmpty() ) - cpp << cppPreamble << endl; - - // Constructor - cpp << cfg.className << "::" << cfg.className << "( "; - if ( cfgFileNameArg ) { - if ( !cfg.singleton && ! cfg.forceStringFilename) - cpp << " KSharedConfig::Ptr config"; - else - cpp << " const QString& config"; - cpp << (parameters.isEmpty() ? " " : ", "); - } - - for (QList<Param>::ConstIterator it = parameters.constBegin(); - it != parameters.constEnd(); ++it) - { - if (it != parameters.constBegin()) - cpp << ","; - cpp << " " << param((*it).type) << " " << (*it).name; - } - cpp << " )" << endl; - - cpp << " : " << cfg.inherits << "("; - if ( !cfgFileName.isEmpty() ) cpp << " QLatin1String( \"" << cfgFileName << "\" "; - if ( cfgFileNameArg ) cpp << " config "; - if ( !cfgFileName.isEmpty() ) cpp << ") "; - cpp << ")" << endl; - - // Store parameters - for (QList<Param>::ConstIterator it = parameters.constBegin(); - it != parameters.constEnd(); ++it) - { - cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl; - } - - if ( hasSignals && !cfg.dpointer ) - cpp << " , " << varName("settingsChanged", cfg) << "(0)" << endl; - - cpp << "{" << endl; - - if (cfg.dpointer) - { - cpp << " d = new " + cfg.className + "Private;" << endl; - if (hasSignals) - cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; - } - // Needed in case the singleton class is used as baseclass for - // another singleton. - if (cfg.singleton) { - cpp << " Q_ASSERT(!s_global" << cfg.className << "()->q);" << endl; - cpp << " s_global" << cfg.className << "()->q = this;" << endl; - } - - group.clear(); - - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - if ( (*itEntry)->group() != group ) { - if ( !group.isEmpty() ) cpp << endl; - group = (*itEntry)->group(); - cpp << " setCurrentGroup( " << paramString(group, parameters) << " );" << endl << endl; - } - - QString key = paramString( (*itEntry)->key(), parameters ); - if ( !(*itEntry)->code().isEmpty() ) { - cpp << (*itEntry)->code() << endl; - } - if ( (*itEntry)->type() == "Enum" ) { - cpp << " QList<"+cfg.inherits+"::ItemEnum::Choice> values" - << (*itEntry)->name() << ";" << endl; - const QList<CfgEntry::Choice> choices = (*itEntry)->choices().choices; - QList<CfgEntry::Choice>::ConstIterator it; - for( it = choices.constBegin(); it != choices.constEnd(); ++it ) { - cpp << " {" << endl; - cpp << " "+cfg.inherits+"::ItemEnum::Choice choice;" << endl; - cpp << " choice.name = QLatin1String(\"" << (*it).name << "\");" << endl; - if ( cfg.setUserTexts ) { - if ( !(*it).label.isEmpty() ) { - cpp << " choice.label = " - << translatedString(cfg, (*it).label, (*it).context) - << ";" << endl; - } - if ( !(*it).toolTip.isEmpty() ) { - cpp << " choice.toolTip = " - << translatedString(cfg, (*it).toolTip, (*it).context) - << ";" << endl; - } - if ( !(*it).whatsThis.isEmpty() ) { - cpp << " choice.whatsThis = " - << translatedString(cfg, (*it).whatsThis, (*it).context) - << ";" << endl; - } - } - cpp << " values" << (*itEntry)->name() << ".append( choice );" << endl; - cpp << " }" << endl; - } - } - - if (!cfg.dpointer) - cpp << itemDeclaration( *itEntry, cfg ); - - if ( (*itEntry)->param().isEmpty() ) - { - // Normal case - cpp << " " << itemPath( *itEntry, cfg ) << " = " - << newItem( (*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue(), cfg ) << endl; + if (cfg.setUserTexts && cfg.translationSystem == CfgConfig::KdeTranslation) { + cpp << "#include <klocalizedstring.h>" << endl << endl; + } - if ( !(*itEntry)->minValue().isEmpty() ) - cpp << " " << itemPath( *itEntry, cfg ) << "->setMinValue(" << (*itEntry)->minValue() << ");" << endl; - if ( !(*itEntry)->maxValue().isEmpty() ) - cpp << " " << itemPath( *itEntry, cfg ) << "->setMaxValue(" << (*itEntry)->maxValue() << ");" << endl; + // Header required by singleton implementation + if (cfg.singleton) { + cpp << "#include <qglobal.h>" << endl << "#include <QtCore/QFile>" << endl << endl; + } + if (cfg.singleton && cfgFileNameArg) { + cpp << "#include <QDebug>" << endl << endl; + } + + if (!cfg.nameSpace.isEmpty()) { + cpp << "using namespace " << cfg.nameSpace << ";" << endl << endl; + } + + QString group; - if ( cfg.setUserTexts ) - cpp << userTextsFunctions( (*itEntry), cfg ); + // private class implementation + if (cfg.dpointer) { + beginNamespaces(cfg.nameSpace, cpp); + cpp << "class " << cfg.className << "Private" << endl; + cpp << "{" << endl; + cpp << " public:" << endl; + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + if ((*itEntry)->group() != group) { + group = (*itEntry)->group(); + cpp << endl; + cpp << " // " << group << endl; + } + cpp << " " << cppType((*itEntry)->type()) << " " << varName((*itEntry)->name(), cfg); + if (!(*itEntry)->param().isEmpty()) { + cpp << QString("[%1]").arg((*itEntry)->paramMax() + 1); + } + cpp << ";" << endl; + } + cpp << endl << " // items" << endl; + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + cpp << " " + cfg.inherits + "::Item" << itemType((*itEntry)->type()) << " *" << itemVar(*itEntry, cfg); + if (!(*itEntry)->param().isEmpty()) { + cpp << QString("[%1]").arg((*itEntry)->paramMax() + 1); + } + cpp << ";" << endl; + } + if (hasSignals) { + cpp << " uint " << varName("settingsChanged", cfg) << ";" << endl; + } - cpp << " addItem( " << itemPath( *itEntry, cfg ); - QString quotedName = (*itEntry)->name(); - addQuotes( quotedName ); - if ( quotedName != key ) cpp << ", QLatin1String( \"" << (*itEntry)->name() << "\" )"; - cpp << " );" << endl; + cpp << "};" << endl << endl; + endNamespaces(cfg.nameSpace, cpp); } - else - { - // Indexed - for(int i = 0; i <= (*itEntry)->paramMax(); i++) - { - QString defaultStr; - QString itemVarStr(itemPath( *itEntry, cfg )+QString("[%1]").arg(i)); - - if ( !(*itEntry)->paramDefaultValue(i).isEmpty() ) - defaultStr = (*itEntry)->paramDefaultValue(i); - else if ( !(*itEntry)->defaultValue().isEmpty() ) - defaultStr = paramString( (*itEntry)->defaultValue(), (*itEntry), i ); - else - defaultStr = defaultValue( (*itEntry)->type() ); - - cpp << " " << itemVarStr << " = " - << newItem( (*itEntry)->type(), (*itEntry)->name(), paramString(key, *itEntry, i), defaultStr,cfg, QString("[%1]").arg(i) ) - << endl; - - if ( cfg.setUserTexts ) - cpp << userTextsFunctions( *itEntry, cfg, itemVarStr, (*itEntry)->paramName() ); - - // Make mutators for enum parameters work by adding them with $(..) replaced by the - // param name. The check for isImmutable in the set* functions doesn't have the param - // name available, just the corresponding enum value (int), so we need to store the - // param names in a separate static list!. - cpp << " addItem( " << itemVarStr << ", QLatin1String( \""; - if ( (*itEntry)->paramType()=="Enum" ) - cpp << (*itEntry)->paramName().replace( "$("+(*itEntry)->param()+')', "%1").arg((*itEntry)->paramValues()[i] ); - else - cpp << (*itEntry)->paramName().replace( "$("+(*itEntry)->param()+')', "%1").arg(i); - cpp << "\" ) );" << endl; - } - } - } - - cpp << "}" << endl << endl; - - if (cfg.dpointer) - { - // setters and getters go in Cpp if in dpointer mode - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - QString n = (*itEntry)->name(); - QString t = (*itEntry)->type(); - - // Manipulator - if (cfg.allMutators || cfg.mutators.contains(n)) - { - cpp << "void " << setFunction(n, cfg.className) << "( "; - if ( !(*itEntry)->param().isEmpty() ) - cpp << cppType( (*itEntry)->paramType() ) << " i, "; - if (cfg.useEnumTypes && t == "Enum") - cpp << enumType(*itEntry, cfg.globalEnums); - else - cpp << param( t ); - cpp << " v )" << endl; - // function body inline only if not using dpointer - // for BC mode + + // Singleton implementation + if (cfg.singleton) { + beginNamespaces(cfg.nameSpace, cpp); + cpp << "class " << cfg.className << "Helper" << endl; + cpp << '{' << endl; + cpp << " public:" << endl; + cpp << " " << cfg.className << "Helper() : q(0) {}" << endl; + cpp << " ~" << cfg.className << "Helper() { delete q; }" << endl; + cpp << " " << cfg.className << " *q;" << endl; + cpp << "};" << endl; + endNamespaces(cfg.nameSpace, cpp); + cpp << "Q_GLOBAL_STATIC(" << cfg.className << "Helper, s_global" << cfg.className << ")" << endl; + + cpp << cfg.className << " *" << cfg.className << "::self()" << endl; cpp << "{" << endl; - cpp << indent(memberMutatorBody( *itEntry, cfg ), 6); + if (cfgFileNameArg) { + cpp << " if (!s_global" << cfg.className << "()->q)" << endl; + cpp << " qFatal(\"you need to call " << cfg.className << "::instance before using\");" << endl; + } else { + cpp << " if (!s_global" << cfg.className << "()->q) {" << endl; + cpp << " new " << cfg.className << ';' << endl; + cpp << " s_global" << cfg.className << "()->q->readConfig();" << endl; + cpp << " }" << endl << endl; + } + cpp << " return s_global" << cfg.className << "()->q;" << endl; cpp << "}" << endl << endl; - } - - // Accessor - if (cfg.useEnumTypes && t == "Enum") - cpp << enumType(*itEntry, cfg.globalEnums); - else - cpp << cppType(t); - cpp << " " << getFunction(n, cfg.className) << "("; - if ( !(*itEntry)->param().isEmpty() ) - cpp << " " << cppType( (*itEntry)->paramType() ) <<" i "; - cpp << ")" << Const << endl; - // function body inline only if not using dpointer - // for BC mode - cpp << "{" << endl; - cpp << indent(memberAccessorBody( *itEntry, cfg.globalEnums, cfg ), 2); - cpp << "}" << endl << endl; - - // Default value Accessor -- written by the loop below - - // Item accessor - if ( cfg.itemAccessors ) - { - cpp << endl; - cpp << cfg.inherits+"::Item" << itemType( (*itEntry)->type() ) << " *" - << getFunction( n, cfg.className ) << "Item("; - if ( !(*itEntry)->param().isEmpty() ) { - cpp << " " << cppType( (*itEntry)->paramType() ) << " i "; + + if (cfgFileNameArg) { + cpp << "void " << cfg.className << "::instance(const QString& cfgfilename)" << endl; + cpp << "{" << endl; + cpp << " if (s_global" << cfg.className << "()->q) {" << endl; + cpp << " qDebug() << \"" << cfg.className << "::instance called after the first use - ignoring\";" << endl; + cpp << " return;" << endl; + cpp << " }" << endl; + cpp << " new " << cfg.className << "(cfgfilename);" << endl; + cpp << " s_global" << cfg.className << "()->q->readConfig();" << endl; + cpp << "}" << endl << endl; } - cpp << ")" << endl; - cpp << "{" << endl; - cpp << indent(itemAccessorBody( *itEntry, cfg ), 2); - cpp << "}" << endl; - } - - cpp << endl; - } - } - - // default value getters always go in Cpp - for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) { - QString n = (*itEntry)->name(); - QString t = (*itEntry)->type(); - - // Default value Accessor, as "helper" function - if (( cfg.allDefaultGetters || cfg.defaultGetters.contains(n) ) && !(*itEntry)->defaultValue().isEmpty() ) { - cpp << cppType(t) << " " << getDefaultFunction(n, cfg.className) << "_helper("; - if ( !(*itEntry)->param().isEmpty() ) - cpp << " " << cppType( (*itEntry)->paramType() ) <<" i "; - cpp << ")" << Const << endl; - cpp << "{" << endl; - cpp << memberGetDefaultBody(*itEntry) << endl; - cpp << "}" << endl << endl; - } - } - - // Destructor - cpp << cfg.className << "::~" << cfg.className << "()" << endl; - cpp << "{" << endl; - if ( cfg.singleton ) { - if ( cfg.dpointer ) - cpp << " delete d;" << endl; - cpp << " s_global" << cfg.className << "()->q = 0;" << endl; - } - cpp << "}" << endl << endl; - - if ( hasSignals ) { - cpp << "bool " << cfg.className << "::" << "usrWriteConfig()" << endl; + } + + if (!cppPreamble.isEmpty()) { + cpp << cppPreamble << endl; + } + + // Constructor + cpp << cfg.className << "::" << cfg.className << "( "; + if (cfgFileNameArg) { + if (!cfg.singleton && ! cfg.forceStringFilename) { + cpp << " KSharedConfig::Ptr config"; + } else { + cpp << " const QString& config"; + } + cpp << (parameters.isEmpty() ? " " : ", "); + } + + for (QList<Param>::ConstIterator it = parameters.constBegin(); + it != parameters.constEnd(); ++it) { + if (it != parameters.constBegin()) { + cpp << ","; + } + cpp << " " << param((*it).type) << " " << (*it).name; + } + cpp << " )" << endl; + + cpp << " : " << cfg.inherits << "("; + if (!cfgFileName.isEmpty()) { + cpp << " QLatin1String( \"" << cfgFileName << "\" "; + } + if (cfgFileNameArg) { + cpp << " config "; + } + if (!cfgFileName.isEmpty()) { + cpp << ") "; + } + cpp << ")" << endl; + + // Store parameters + for (QList<Param>::ConstIterator it = parameters.constBegin(); + it != parameters.constEnd(); ++it) { + cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl; + } + + if (hasSignals && !cfg.dpointer) { + cpp << " , " << varName("settingsChanged", cfg) << "(0)" << endl; + } + + cpp << "{" << endl; + + if (cfg.dpointer) { + cpp << " d = new " + cfg.className + "Private;" << endl; + if (hasSignals) { + cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; + } + } + // Needed in case the singleton class is used as baseclass for + // another singleton. + if (cfg.singleton) { + cpp << " Q_ASSERT(!s_global" << cfg.className << "()->q);" << endl; + cpp << " s_global" << cfg.className << "()->q = this;" << endl; + } + + group.clear(); + + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + if ((*itEntry)->group() != group) { + if (!group.isEmpty()) { + cpp << endl; + } + group = (*itEntry)->group(); + cpp << " setCurrentGroup( " << paramString(group, parameters) << " );" << endl << endl; + } + + QString key = paramString((*itEntry)->key(), parameters); + if (!(*itEntry)->code().isEmpty()) { + cpp << (*itEntry)->code() << endl; + } + if ((*itEntry)->type() == "Enum") { + cpp << " QList<" + cfg.inherits + "::ItemEnum::Choice> values" + << (*itEntry)->name() << ";" << endl; + const QList<CfgEntry::Choice> choices = (*itEntry)->choices().choices; + QList<CfgEntry::Choice>::ConstIterator it; + for (it = choices.constBegin(); it != choices.constEnd(); ++it) { + cpp << " {" << endl; + cpp << " " + cfg.inherits + "::ItemEnum::Choice choice;" << endl; + cpp << " choice.name = QLatin1String(\"" << (*it).name << "\");" << endl; + if (cfg.setUserTexts) { + if (!(*it).label.isEmpty()) { + cpp << " choice.label = " + << translatedString(cfg, (*it).label, (*it).context) + << ";" << endl; + } + if (!(*it).toolTip.isEmpty()) { + cpp << " choice.toolTip = " + << translatedString(cfg, (*it).toolTip, (*it).context) + << ";" << endl; + } + if (!(*it).whatsThis.isEmpty()) { + cpp << " choice.whatsThis = " + << translatedString(cfg, (*it).whatsThis, (*it).context) + << ";" << endl; + } + } + cpp << " values" << (*itEntry)->name() << ".append( choice );" << endl; + cpp << " }" << endl; + } + } + + if (!cfg.dpointer) { + cpp << itemDeclaration(*itEntry, cfg); + } + + if ((*itEntry)->param().isEmpty()) { + // Normal case + cpp << " " << itemPath(*itEntry, cfg) << " = " + << newItem((*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue(), cfg) << endl; + + if (!(*itEntry)->minValue().isEmpty()) { + cpp << " " << itemPath(*itEntry, cfg) << "->setMinValue(" << (*itEntry)->minValue() << ");" << endl; + } + if (!(*itEntry)->maxValue().isEmpty()) { + cpp << " " << itemPath(*itEntry, cfg) << "->setMaxValue(" << (*itEntry)->maxValue() << ");" << endl; + } + + if (cfg.setUserTexts) { + cpp << userTextsFunctions((*itEntry), cfg); + } + + cpp << " addItem( " << itemPath(*itEntry, cfg); + QString quotedName = (*itEntry)->name(); + addQuotes(quotedName); + if (quotedName != key) { + cpp << ", QLatin1String( \"" << (*itEntry)->name() << "\" )"; + } + cpp << " );" << endl; + } else { + // Indexed + for (int i = 0; i <= (*itEntry)->paramMax(); i++) { + QString defaultStr; + QString itemVarStr(itemPath(*itEntry, cfg) + QString("[%1]").arg(i)); + + if (!(*itEntry)->paramDefaultValue(i).isEmpty()) { + defaultStr = (*itEntry)->paramDefaultValue(i); + } else if (!(*itEntry)->defaultValue().isEmpty()) { + defaultStr = paramString((*itEntry)->defaultValue(), (*itEntry), i); + } else { + defaultStr = defaultValue((*itEntry)->type()); + } + + cpp << " " << itemVarStr << " = " + << newItem((*itEntry)->type(), (*itEntry)->name(), paramString(key, *itEntry, i), defaultStr, cfg, QString("[%1]").arg(i)) + << endl; + + if (cfg.setUserTexts) { + cpp << userTextsFunctions(*itEntry, cfg, itemVarStr, (*itEntry)->paramName()); + } + + // Make mutators for enum parameters work by adding them with $(..) replaced by the + // param name. The check for isImmutable in the set* functions doesn't have the param + // name available, just the corresponding enum value (int), so we need to store the + // param names in a separate static list!. + cpp << " addItem( " << itemVarStr << ", QLatin1String( \""; + if ((*itEntry)->paramType() == "Enum") { + cpp << (*itEntry)->paramName().replace("$(" + (*itEntry)->param() + ')', "%1").arg((*itEntry)->paramValues()[i]); + } else { + cpp << (*itEntry)->paramName().replace("$(" + (*itEntry)->param() + ')', "%1").arg(i); + } + cpp << "\" ) );" << endl; + } + } + } + + cpp << "}" << endl << endl; + + if (cfg.dpointer) { + // setters and getters go in Cpp if in dpointer mode + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + QString n = (*itEntry)->name(); + QString t = (*itEntry)->type(); + + // Manipulator + if (cfg.allMutators || cfg.mutators.contains(n)) { + cpp << "void " << setFunction(n, cfg.className) << "( "; + if (!(*itEntry)->param().isEmpty()) { + cpp << cppType((*itEntry)->paramType()) << " i, "; + } + if (cfg.useEnumTypes && t == "Enum") { + cpp << enumType(*itEntry, cfg.globalEnums); + } else { + cpp << param(t); + } + cpp << " v )" << endl; + // function body inline only if not using dpointer + // for BC mode + cpp << "{" << endl; + cpp << indent(memberMutatorBody(*itEntry, cfg), 6); + cpp << "}" << endl << endl; + } + + // Accessor + if (cfg.useEnumTypes && t == "Enum") { + cpp << enumType(*itEntry, cfg.globalEnums); + } else { + cpp << cppType(t); + } + cpp << " " << getFunction(n, cfg.className) << "("; + if (!(*itEntry)->param().isEmpty()) { + cpp << " " << cppType((*itEntry)->paramType()) << " i "; + } + cpp << ")" << Const << endl; + // function body inline only if not using dpointer + // for BC mode + cpp << "{" << endl; + cpp << indent(memberAccessorBody(*itEntry, cfg.globalEnums, cfg), 2); + cpp << "}" << endl << endl; + + // Default value Accessor -- written by the loop below + + // Item accessor + if (cfg.itemAccessors) { + cpp << endl; + cpp << cfg.inherits + "::Item" << itemType((*itEntry)->type()) << " *" + << getFunction(n, cfg.className) << "Item("; + if (!(*itEntry)->param().isEmpty()) { + cpp << " " << cppType((*itEntry)->paramType()) << " i "; + } + cpp << ")" << endl; + cpp << "{" << endl; + cpp << indent(itemAccessorBody(*itEntry, cfg), 2); + cpp << "}" << endl; + } + + cpp << endl; + } + } + + // default value getters always go in Cpp + for (itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry) { + QString n = (*itEntry)->name(); + QString t = (*itEntry)->type(); + + // Default value Accessor, as "helper" function + if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) { + cpp << cppType(t) << " " << getDefaultFunction(n, cfg.className) << "_helper("; + if (!(*itEntry)->param().isEmpty()) { + cpp << " " << cppType((*itEntry)->paramType()) << " i "; + } + cpp << ")" << Const << endl; + cpp << "{" << endl; + cpp << memberGetDefaultBody(*itEntry) << endl; + cpp << "}" << endl << endl; + } + } + + // Destructor + cpp << cfg.className << "::~" << cfg.className << "()" << endl; cpp << "{" << endl; - cpp << " const bool res = " << cfg.inherits << "::usrWriteConfig();" << endl; - cpp << " if (!res) return false;" << endl << endl; - Q_FOREACH(const Signal &signal, signalList) { - cpp << " if ( " << varPath("settingsChanged", cfg) << " & " << signalEnumName(signal.name) << " ) " << endl; - cpp << " emit " << signal.name << "("; - QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); - for ( it = signal.arguments.constBegin(); it != itEnd; ) { - SignalArguments argument = *it; - bool cast = false; - if ( cfg.useEnumTypes && argument.type == "Enum" ) { - for ( int i = 0, end = entries.count(); i < end; ++i ) { - if ( entries[i]->name() == argument.variableName ) { - cpp << "static_cast<" << enumType(entries[i], cfg.globalEnums) << ">("; - cast = true; - break; + if (cfg.singleton) { + if (cfg.dpointer) { + cpp << " delete d;" << endl; + } + cpp << " s_global" << cfg.className << "()->q = 0;" << endl; + } + cpp << "}" << endl << endl; + + if (hasSignals) { + cpp << "bool " << cfg.className << "::" << "usrWriteConfig()" << endl; + cpp << "{" << endl; + cpp << " const bool res = " << cfg.inherits << "::usrWriteConfig();" << endl; + cpp << " if (!res) return false;" << endl << endl; + Q_FOREACH (const Signal &signal, signalList) { + cpp << " if ( " << varPath("settingsChanged", cfg) << " & " << signalEnumName(signal.name) << " ) " << endl; + cpp << " emit " << signal.name << "("; + QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd(); + for (it = signal.arguments.constBegin(); it != itEnd;) { + SignalArguments argument = *it; + bool cast = false; + if (cfg.useEnumTypes && argument.type == "Enum") { + for (int i = 0, end = entries.count(); i < end; ++i) { + if (entries[i]->name() == argument.variableName) { + cpp << "static_cast<" << enumType(entries[i], cfg.globalEnums) << ">("; + cast = true; + break; + } + } + } + cpp << varPath(argument.variableName, cfg); + if (cast) { + cpp << ")"; + } + if (++it != itEnd) { + cpp << ", "; + } } - } - } - cpp << varPath(argument.variableName, cfg); - if ( cast ) - cpp << ")"; - if ( ++it != itEnd ) - cpp << ", "; - } - cpp << ");" << endl << endl; - } - cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; - cpp << " return true;" << endl; - cpp << "}" << endl; - } - - // Add includemoc if they are signals defined. - if( hasSignals ) { - cpp << endl; - cpp << "#include \"" << mocFileName << "\"" << endl; - cpp << endl; - } - - // clear entries list - qDeleteAll( entries ); - - implementation.close(); + cpp << ");" << endl << endl; + } + cpp << " " << varPath("settingsChanged", cfg) << " = 0;" << endl; + cpp << " return true;" << endl; + cpp << "}" << endl; + } + + // Add includemoc if they are signals defined. + if (hasSignals) { + cpp << endl; + cpp << "#include \"" << mocFileName << "\"" << endl; + cpp << endl; + } + + // clear entries list + qDeleteAll(entries); + + implementation.close(); } |