undefined
17-07-2008, 18:11
Schreibe gerade an einer Qt Bibliothek und versuche hierbei innerhalb eines Namespace eine eigene Konfigurations Klasse zu schreiben in der ich mit Qsettings::registerFormat das Datenkonstrukt neu erstelle. Das funktioniert auch alles so weit nur kann ich nicht meine Funktionen die von QSettings als typedef Definiert sind in meine Klassen aufnehmen. Sobald ich das mache gibt es ein undefined Symbols.
Header:
#ifndef QTIDY_H
#define QTIDY_H
#include "tidy.h"
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QSettings>
namespace QTidy
{
class Config : private QSettings
{
Q_OBJECT
public:
explicit Config ( const QString &configFile = 0 );
void setValue ( const QString ¶m, const QVariant &value );
QVariant value ( const QString ¶m, const QVariant &dValue = QVariant() );
~Config();
private:
bool ConfigStatus;
QSettings *m_QSettings;
QString cfgFile;
bool ParseConfigFile ( const QString &file, QSettings::Scope scope = QSettings::UserScope );
}; /* eof QTidy::Config */
} /* eof namespace QTidy */
#endif
CPP File:
#include "QTidy.h"
/* QtCore */
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QSettings>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QByteArray>
#include <QtCore/QMap>
#include <QtCore/QDebug>
namespace QTidy
{
bool readTidyrc ( QIODevice &device, QSettings::SettingsMap &map )
{
if ( device.isOpen () )
{
if ( ! map.empty() )
map.clear();
while ( ! device.atEnd() )
{
QByteArray line = device.readLine().trimmed();
if ( ! line.startsWith ( "#" ) && line.contains ( ":" ) )
{
QStringList tmp = QString ( line ).split ( ":" );
const QString key ( tmp.at ( 0 ).trimmed() );
const QString val ( tmp.at ( 1 ).trimmed() );
if ( ! key.isEmpty() && ! val.isEmpty() )
{
if ( val.contains ( QRegExp ( "^(yes|no)$" ) ) )
map.insert ( key, QVariant ( val.contains ( "yes" ) ) );
else if ( val.contains ( QRegExp ( "^[0-9]+$" ) ) )
map.insert ( key, QVariant ( val ).toInt() );
else
map.insert ( key, QVariant ( val ) );
}
tmp.clear();
}
}
return true;
}
return false;
}
bool writeTidyrc ( QIODevice &device, const QSettings::SettingsMap &map )
{
if ( device.isOpen () && ! map.empty() )
{
QMap<QString,QVariant>::const_iterator it;
for ( it = map.begin(); it != map.end(); ++it )
{
QString buffer;
QString val = it.value().toString();
if ( val == "true" )
buffer = QString ( "%1: yes\n" ).arg ( it.key() );
else if ( val == "false" )
buffer = QString ( "%1: no\n" ).arg ( it.key() );
else
buffer = QString ( "%1: %2\n" ).arg ( it.key(), val );
if ( ! buffer.isEmpty() )
device.write ( buffer.toAscii() );
buffer.clear();
}
return true;
}
return false;
}
/* Configuration */
Config::Config ( const QString &configFile )
{
ConfigStatus = false;
QStringList files;
if ( ! configFile.isEmpty() )
files << configFile;
/* @see TIDY_USER_CONFIG_FILE:$(tidy_source)/include/platform.h */
files << "~/.tidyrc";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::UserScope ) )
{
ConfigStatus = true;
break;
}
}
/* @see TIDY_CONFIG_FILE:$(tidy_source)/include/platform.h */
if ( ! ConfigStatus )
{
files.clear();
files << "/etc/tidy.conf" << "/etc/tidyrc" << "/etc/tidy_config.txt";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::SystemScope ) )
{
ConfigStatus = true;
break;
}
}
}
}
bool Config::ParseConfigFile ( const QString &file, QSettings::Scope scope )
{
QFileInfo cfg;
if ( scope == QSettings::UserScope )
cfg.setFile ( QDir::home(), QFileInfo ( file ).fileName() );
else
cfg.setFile ( file );
if ( cfg.exists() )
{
if ( ! cfg.isWritable() )
{
qCritical ( "Permission Denied for '%s'!", qPrintable ( file ) );
return false;
}
const QSettings::Format format = QSettings::registerFormat ( "",
QTidy::readTidyrc, QTidy::writeTidyrc );
m_QSettings = new QSettings ( cfg.absoluteFilePath(), format );
if ( m_QSettings->status() == QSettings::NoError )
{
ConfigStatus = true;
cfgFile = cfg.absoluteFilePath();
return true;
}
}
return false;
}
void Config::setValue ( const QString ¶m, const QVariant &value )
{
if ( ConfigStatus )
m_QSettings->setValue ( param, value );
}
QVariant Config::value ( const QString ¶m, const QVariant &dValue )
{
if ( ConfigStatus )
return m_QSettings->value ( param, dValue );
else
return QVariant();
}
Config::~Config()
{}
} /* namespace QTidy */
In der Docu von QT steht das diese Funktion Threadsave ist, und ein Pointer auf den Funktionen liegt, kann es sein das es daran liegt oder wo habe ich hier den Fehler?
In den Quellen von qt unter src/corelib/io/qsettings.h wird’s wie folgt definiert.
typedef QMap<QString, QVariant> SettingsMap;
typedef bool (*ReadFunc)(QIODevice &device, SettingsMap &map);
typedef bool (*WriteFunc)(QIODevice &device, const SettingsMap &map);
static Format registerFormat(const QString &extension, ReadFunc readFunc, WriteFunc writeFunc,
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive);
Header:
#ifndef QTIDY_H
#define QTIDY_H
#include "tidy.h"
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QSettings>
namespace QTidy
{
class Config : private QSettings
{
Q_OBJECT
public:
explicit Config ( const QString &configFile = 0 );
void setValue ( const QString ¶m, const QVariant &value );
QVariant value ( const QString ¶m, const QVariant &dValue = QVariant() );
~Config();
private:
bool ConfigStatus;
QSettings *m_QSettings;
QString cfgFile;
bool ParseConfigFile ( const QString &file, QSettings::Scope scope = QSettings::UserScope );
}; /* eof QTidy::Config */
} /* eof namespace QTidy */
#endif
CPP File:
#include "QTidy.h"
/* QtCore */
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QSettings>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QByteArray>
#include <QtCore/QMap>
#include <QtCore/QDebug>
namespace QTidy
{
bool readTidyrc ( QIODevice &device, QSettings::SettingsMap &map )
{
if ( device.isOpen () )
{
if ( ! map.empty() )
map.clear();
while ( ! device.atEnd() )
{
QByteArray line = device.readLine().trimmed();
if ( ! line.startsWith ( "#" ) && line.contains ( ":" ) )
{
QStringList tmp = QString ( line ).split ( ":" );
const QString key ( tmp.at ( 0 ).trimmed() );
const QString val ( tmp.at ( 1 ).trimmed() );
if ( ! key.isEmpty() && ! val.isEmpty() )
{
if ( val.contains ( QRegExp ( "^(yes|no)$" ) ) )
map.insert ( key, QVariant ( val.contains ( "yes" ) ) );
else if ( val.contains ( QRegExp ( "^[0-9]+$" ) ) )
map.insert ( key, QVariant ( val ).toInt() );
else
map.insert ( key, QVariant ( val ) );
}
tmp.clear();
}
}
return true;
}
return false;
}
bool writeTidyrc ( QIODevice &device, const QSettings::SettingsMap &map )
{
if ( device.isOpen () && ! map.empty() )
{
QMap<QString,QVariant>::const_iterator it;
for ( it = map.begin(); it != map.end(); ++it )
{
QString buffer;
QString val = it.value().toString();
if ( val == "true" )
buffer = QString ( "%1: yes\n" ).arg ( it.key() );
else if ( val == "false" )
buffer = QString ( "%1: no\n" ).arg ( it.key() );
else
buffer = QString ( "%1: %2\n" ).arg ( it.key(), val );
if ( ! buffer.isEmpty() )
device.write ( buffer.toAscii() );
buffer.clear();
}
return true;
}
return false;
}
/* Configuration */
Config::Config ( const QString &configFile )
{
ConfigStatus = false;
QStringList files;
if ( ! configFile.isEmpty() )
files << configFile;
/* @see TIDY_USER_CONFIG_FILE:$(tidy_source)/include/platform.h */
files << "~/.tidyrc";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::UserScope ) )
{
ConfigStatus = true;
break;
}
}
/* @see TIDY_CONFIG_FILE:$(tidy_source)/include/platform.h */
if ( ! ConfigStatus )
{
files.clear();
files << "/etc/tidy.conf" << "/etc/tidyrc" << "/etc/tidy_config.txt";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::SystemScope ) )
{
ConfigStatus = true;
break;
}
}
}
}
bool Config::ParseConfigFile ( const QString &file, QSettings::Scope scope )
{
QFileInfo cfg;
if ( scope == QSettings::UserScope )
cfg.setFile ( QDir::home(), QFileInfo ( file ).fileName() );
else
cfg.setFile ( file );
if ( cfg.exists() )
{
if ( ! cfg.isWritable() )
{
qCritical ( "Permission Denied for '%s'!", qPrintable ( file ) );
return false;
}
const QSettings::Format format = QSettings::registerFormat ( "",
QTidy::readTidyrc, QTidy::writeTidyrc );
m_QSettings = new QSettings ( cfg.absoluteFilePath(), format );
if ( m_QSettings->status() == QSettings::NoError )
{
ConfigStatus = true;
cfgFile = cfg.absoluteFilePath();
return true;
}
}
return false;
}
void Config::setValue ( const QString ¶m, const QVariant &value )
{
if ( ConfigStatus )
m_QSettings->setValue ( param, value );
}
QVariant Config::value ( const QString ¶m, const QVariant &dValue )
{
if ( ConfigStatus )
return m_QSettings->value ( param, dValue );
else
return QVariant();
}
Config::~Config()
{}
} /* namespace QTidy */
In der Docu von QT steht das diese Funktion Threadsave ist, und ein Pointer auf den Funktionen liegt, kann es sein das es daran liegt oder wo habe ich hier den Fehler?
In den Quellen von qt unter src/corelib/io/qsettings.h wird’s wie folgt definiert.
typedef QMap<QString, QVariant> SettingsMap;
typedef bool (*ReadFunc)(QIODevice &device, SettingsMap &map);
typedef bool (*WriteFunc)(QIODevice &device, const SettingsMap &map);
static Format registerFormat(const QString &extension, ReadFunc readFunc, WriteFunc writeFunc,
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive);