forked from qt-creator/qt-creator
BareMetal: Streamline GdbServerProvider code
Combine host and port values in a url object which is elsewhere typically used, and move the member to the base class as all current providers have something like that. Base typeDisplayName on a datamember, and provide a reusable base implementation of channelString() Change-Id: Iedac09bb80d0bc1818cd88b0de99794e951999b8 Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
@@ -113,7 +113,7 @@ void BareMetalDebugSupport::start()
|
|||||||
setStartMode(AttachToRemoteServer);
|
setStartMode(AttachToRemoteServer);
|
||||||
setCommandsAfterConnect(p->initCommands()); // .. and here?
|
setCommandsAfterConnect(p->initCommands()); // .. and here?
|
||||||
setCommandsForReset(p->resetCommands());
|
setCommandsForReset(p->resetCommands());
|
||||||
setRemoteChannel(p->channel());
|
setRemoteChannel(p->channelString());
|
||||||
setUseContinueInsteadOfRun(true);
|
setUseContinueInsteadOfRun(true);
|
||||||
setUseExtendedRemote(p->useExtendedRemote());
|
setUseExtendedRemote(p->useExtendedRemote());
|
||||||
|
|
||||||
|
@@ -95,7 +95,7 @@ void BareMetalDevice::providerUpdated(GdbServerProvider *provider)
|
|||||||
void BareMetalDevice::setChannelByServerProvider(GdbServerProvider *provider)
|
void BareMetalDevice::setChannelByServerProvider(GdbServerProvider *provider)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(provider, return);
|
QTC_ASSERT(provider, return);
|
||||||
const QString channel = provider->channel();
|
const QString channel = provider->channelString();
|
||||||
const int colon = channel.indexOf(QLatin1Char(':'));
|
const int colon = channel.indexOf(QLatin1Char(':'));
|
||||||
if (colon < 0)
|
if (colon < 0)
|
||||||
return;
|
return;
|
||||||
@@ -116,9 +116,8 @@ void BareMetalDevice::fromMap(const QVariantMap &map)
|
|||||||
} else {
|
} else {
|
||||||
const QSsh::SshConnectionParameters sshParams = sshParameters();
|
const QSsh::SshConnectionParameters sshParams = sshParameters();
|
||||||
const auto newProvider = new DefaultGdbServerProvider;
|
const auto newProvider = new DefaultGdbServerProvider;
|
||||||
|
newProvider->setChannel(sshParams.url);
|
||||||
newProvider->setDisplayName(name);
|
newProvider->setDisplayName(name);
|
||||||
newProvider->m_host = sshParams.host();
|
|
||||||
newProvider->m_port = sshParams.port();
|
|
||||||
if (GdbServerProviderManager::registerProvider(newProvider))
|
if (GdbServerProviderManager::registerProvider(newProvider))
|
||||||
gdbServerProvider = newProvider->id();
|
gdbServerProvider = newProvider->id();
|
||||||
else
|
else
|
||||||
|
@@ -38,62 +38,14 @@
|
|||||||
namespace BareMetal {
|
namespace BareMetal {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static const char hostKeyC[] = "BareMetal.DefaultGdbServerProvider.Host";
|
|
||||||
static const char portKeyC[] = "BareMetal.DefaultGdbServerProvider.Port";
|
|
||||||
|
|
||||||
// DefaultGdbServerProvider
|
// DefaultGdbServerProvider
|
||||||
|
|
||||||
DefaultGdbServerProvider::DefaultGdbServerProvider()
|
DefaultGdbServerProvider::DefaultGdbServerProvider()
|
||||||
: GdbServerProvider(QLatin1String(Constants::DEFAULT_PROVIDER_ID))
|
: GdbServerProvider(QLatin1String(Constants::DEFAULT_PROVIDER_ID))
|
||||||
{
|
{
|
||||||
}
|
setDefaultChannel("localhost", 3333);
|
||||||
|
setSettingsKeyBase("BareMetal.DefaultGdbServerProvider");
|
||||||
DefaultGdbServerProvider::DefaultGdbServerProvider(const DefaultGdbServerProvider &other) = default;
|
setTypeDisplayName(DefaultGdbServerProviderFactory::tr("Default"));
|
||||||
|
|
||||||
quint16 DefaultGdbServerProvider::port() const
|
|
||||||
{
|
|
||||||
return m_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultGdbServerProvider::setPort(const quint16 &port)
|
|
||||||
{
|
|
||||||
m_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DefaultGdbServerProvider::host() const
|
|
||||||
{
|
|
||||||
return m_host;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultGdbServerProvider::setHost(const QString &host)
|
|
||||||
{
|
|
||||||
if (m_host == host)
|
|
||||||
return;
|
|
||||||
m_host = host;
|
|
||||||
providerUpdated();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DefaultGdbServerProvider::typeDisplayName() const
|
|
||||||
{
|
|
||||||
return DefaultGdbServerProviderFactory::tr("Default");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DefaultGdbServerProvider::channel() const
|
|
||||||
{
|
|
||||||
// Just return as "host:port" form.
|
|
||||||
if (m_port == 0)
|
|
||||||
return m_host;
|
|
||||||
return m_host + QLatin1Char(':') + QString::number(m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DefaultGdbServerProvider::isValid() const
|
|
||||||
{
|
|
||||||
if (!GdbServerProvider::isValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_host.isEmpty())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdbServerProvider *DefaultGdbServerProvider::clone() const
|
GdbServerProvider *DefaultGdbServerProvider::clone() const
|
||||||
@@ -101,33 +53,6 @@ GdbServerProvider *DefaultGdbServerProvider::clone() const
|
|||||||
return new DefaultGdbServerProvider(*this);
|
return new DefaultGdbServerProvider(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap DefaultGdbServerProvider::toMap() const
|
|
||||||
{
|
|
||||||
auto data = GdbServerProvider::toMap();
|
|
||||||
data.insert(QLatin1String(hostKeyC), m_host);
|
|
||||||
data.insert(QLatin1String(portKeyC), m_port);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DefaultGdbServerProvider::fromMap(const QVariantMap &data)
|
|
||||||
{
|
|
||||||
if (!GdbServerProvider::fromMap(data))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_host = data.value(QLatin1String(hostKeyC)).toString();
|
|
||||||
m_port = data.value(QLatin1String(portKeyC)).toInt();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DefaultGdbServerProvider::operator==(const GdbServerProvider &other) const
|
|
||||||
{
|
|
||||||
if (!GdbServerProvider::operator==(other))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto p = static_cast<const DefaultGdbServerProvider *>(&other);
|
|
||||||
return m_host == p->m_host && m_port == p->m_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdbServerProviderConfigWidget *DefaultGdbServerProvider::configurationWidget()
|
GdbServerProviderConfigWidget *DefaultGdbServerProvider::configurationWidget()
|
||||||
{
|
{
|
||||||
return new DefaultGdbServerProviderConfigWidget(this);
|
return new DefaultGdbServerProviderConfigWidget(this);
|
||||||
@@ -206,8 +131,7 @@ void DefaultGdbServerProviderConfigWidget::applyImpl()
|
|||||||
auto p = static_cast<DefaultGdbServerProvider *>(provider());
|
auto p = static_cast<DefaultGdbServerProvider *>(provider());
|
||||||
Q_ASSERT(p);
|
Q_ASSERT(p);
|
||||||
|
|
||||||
p->setHost(m_hostWidget->host());
|
p->setChannel(m_hostWidget->channel());
|
||||||
p->setPort(m_hostWidget->port());
|
|
||||||
p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked());
|
p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked());
|
||||||
p->setInitCommands(m_initCommandsTextEdit->toPlainText());
|
p->setInitCommands(m_initCommandsTextEdit->toPlainText());
|
||||||
p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
|
p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
|
||||||
@@ -224,8 +148,7 @@ void DefaultGdbServerProviderConfigWidget::setFromProvider()
|
|||||||
Q_ASSERT(p);
|
Q_ASSERT(p);
|
||||||
|
|
||||||
const QSignalBlocker blocker(this);
|
const QSignalBlocker blocker(this);
|
||||||
m_hostWidget->setHost(p->m_host);
|
m_hostWidget->setChannel(p->channel());
|
||||||
m_hostWidget->setPort(p->m_port);
|
|
||||||
m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote());
|
m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote());
|
||||||
m_initCommandsTextEdit->setPlainText(p->initCommands());
|
m_initCommandsTextEdit->setPlainText(p->initCommands());
|
||||||
m_resetCommandsTextEdit->setPlainText(p->resetCommands());
|
m_resetCommandsTextEdit->setPlainText(p->resetCommands());
|
||||||
|
@@ -38,32 +38,11 @@ class DefaultGdbServerProviderFactory;
|
|||||||
class DefaultGdbServerProvider final : public GdbServerProvider
|
class DefaultGdbServerProvider final : public GdbServerProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString typeDisplayName() const final;
|
|
||||||
|
|
||||||
QVariantMap toMap() const final;
|
|
||||||
bool fromMap(const QVariantMap &data) final;
|
|
||||||
|
|
||||||
bool operator==(const GdbServerProvider &) const final;
|
|
||||||
|
|
||||||
GdbServerProviderConfigWidget *configurationWidget() final;
|
GdbServerProviderConfigWidget *configurationWidget() final;
|
||||||
GdbServerProvider *clone() const final;
|
GdbServerProvider *clone() const final;
|
||||||
|
|
||||||
QString channel() const final;
|
|
||||||
|
|
||||||
bool isValid() const final;
|
|
||||||
|
|
||||||
QString host() const;
|
|
||||||
void setHost(const QString &host);
|
|
||||||
|
|
||||||
quint16 port() const;
|
|
||||||
void setPort(const quint16 &port);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DefaultGdbServerProvider();
|
explicit DefaultGdbServerProvider();
|
||||||
explicit DefaultGdbServerProvider(const DefaultGdbServerProvider &);
|
|
||||||
|
|
||||||
QString m_host = QLatin1String("localhost");
|
|
||||||
quint16 m_port = 3333;
|
|
||||||
|
|
||||||
friend class DefaultGdbServerProviderConfigWidget;
|
friend class DefaultGdbServerProviderConfigWidget;
|
||||||
friend class DefaultGdbServerProviderFactory;
|
friend class DefaultGdbServerProviderFactory;
|
||||||
|
@@ -49,6 +49,9 @@ const char initCommandsKeyC[] = "BareMetal.GdbServerProvider.InitCommands";
|
|||||||
const char resetCommandsKeyC[] = "BareMetal.GdbServerProvider.ResetCommands";
|
const char resetCommandsKeyC[] = "BareMetal.GdbServerProvider.ResetCommands";
|
||||||
const char useExtendedRemoteKeyC[] = "BareMetal.GdbServerProvider.UseExtendedRemote";
|
const char useExtendedRemoteKeyC[] = "BareMetal.GdbServerProvider.UseExtendedRemote";
|
||||||
|
|
||||||
|
const char hostKeySuffixC[] = ".Host";
|
||||||
|
const char portKeySuffixC[] = ".Port";
|
||||||
|
|
||||||
static QString createId(const QString &id)
|
static QString createId(const QString &id)
|
||||||
{
|
{
|
||||||
QString newId = id.left(id.indexOf(QLatin1Char(':')));
|
QString newId = id.left(id.indexOf(QLatin1Char(':')));
|
||||||
@@ -128,6 +131,11 @@ bool GdbServerProvider::useExtendedRemote() const
|
|||||||
return m_useExtendedRemote;
|
return m_useExtendedRemote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GdbServerProvider::typeDisplayName() const
|
||||||
|
{
|
||||||
|
return m_typeDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
void GdbServerProvider::setUseExtendedRemote(bool useExtendedRemote)
|
void GdbServerProvider::setUseExtendedRemote(bool useExtendedRemote)
|
||||||
{
|
{
|
||||||
m_useExtendedRemote = useExtendedRemote;
|
m_useExtendedRemote = useExtendedRemote;
|
||||||
@@ -143,6 +151,22 @@ void GdbServerProvider::setResetCommands(const QString &cmds)
|
|||||||
m_resetCommands = cmds;
|
m_resetCommands = cmds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbServerProvider::setChannel(const QUrl &channel)
|
||||||
|
{
|
||||||
|
m_channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GdbServerProvider::setDefaultChannel(const QString &host, int port)
|
||||||
|
{
|
||||||
|
m_channel.setHost(host);
|
||||||
|
m_channel.setPort(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl GdbServerProvider::channel() const
|
||||||
|
{
|
||||||
|
return m_channel;
|
||||||
|
}
|
||||||
|
|
||||||
Utils::CommandLine GdbServerProvider::command() const
|
Utils::CommandLine GdbServerProvider::command() const
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@@ -158,12 +182,21 @@ bool GdbServerProvider::operator==(const GdbServerProvider &other) const
|
|||||||
|
|
||||||
// We ignore displayname
|
// We ignore displayname
|
||||||
return thisId == otherId
|
return thisId == otherId
|
||||||
|
&& m_channel == other.m_channel
|
||||||
&& m_startupMode == other.m_startupMode
|
&& m_startupMode == other.m_startupMode
|
||||||
&& m_initCommands == other.m_initCommands
|
&& m_initCommands == other.m_initCommands
|
||||||
&& m_resetCommands == other.m_resetCommands
|
&& m_resetCommands == other.m_resetCommands
|
||||||
&& m_useExtendedRemote == other.m_useExtendedRemote;
|
&& m_useExtendedRemote == other.m_useExtendedRemote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GdbServerProvider::channelString() const
|
||||||
|
{
|
||||||
|
// Just return as "host:port" form.
|
||||||
|
if (m_channel.port() <= 0)
|
||||||
|
return m_channel.host();
|
||||||
|
return m_channel.host() + ':' + QString::number(m_channel.port());
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap GdbServerProvider::toMap() const
|
QVariantMap GdbServerProvider::toMap() const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
@@ -173,12 +206,14 @@ QVariantMap GdbServerProvider::toMap() const
|
|||||||
{QLatin1String(initCommandsKeyC), m_initCommands},
|
{QLatin1String(initCommandsKeyC), m_initCommands},
|
||||||
{QLatin1String(resetCommandsKeyC), m_resetCommands},
|
{QLatin1String(resetCommandsKeyC), m_resetCommands},
|
||||||
{QLatin1String(useExtendedRemoteKeyC), m_useExtendedRemote},
|
{QLatin1String(useExtendedRemoteKeyC), m_useExtendedRemote},
|
||||||
|
{m_settingsBase + hostKeySuffixC, m_channel.host()},
|
||||||
|
{m_settingsBase + portKeySuffixC, m_channel.port()},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GdbServerProvider::isValid() const
|
bool GdbServerProvider::isValid() const
|
||||||
{
|
{
|
||||||
return !channel().isNull();
|
return !channelString().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GdbServerProvider::canStartupMode(StartupMode m) const
|
bool GdbServerProvider::canStartupMode(StartupMode m) const
|
||||||
@@ -211,9 +246,22 @@ bool GdbServerProvider::fromMap(const QVariantMap &data)
|
|||||||
m_initCommands = data.value(QLatin1String(initCommandsKeyC)).toString();
|
m_initCommands = data.value(QLatin1String(initCommandsKeyC)).toString();
|
||||||
m_resetCommands = data.value(QLatin1String(resetCommandsKeyC)).toString();
|
m_resetCommands = data.value(QLatin1String(resetCommandsKeyC)).toString();
|
||||||
m_useExtendedRemote = data.value(QLatin1String(useExtendedRemoteKeyC)).toBool();
|
m_useExtendedRemote = data.value(QLatin1String(useExtendedRemoteKeyC)).toBool();
|
||||||
|
m_channel.setHost(data.value(m_settingsBase + hostKeySuffixC).toString());
|
||||||
|
m_channel.setPort(data.value(m_settingsBase + portKeySuffixC).toInt());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbServerProvider::setTypeDisplayName(const QString &typeDisplayName)
|
||||||
|
{
|
||||||
|
m_typeDisplayName = typeDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GdbServerProvider::setSettingsKeyBase(const QString &settingsBase)
|
||||||
|
{
|
||||||
|
m_settingsBase = settingsBase;
|
||||||
|
}
|
||||||
|
|
||||||
// GdbServerProviderFactory
|
// GdbServerProviderFactory
|
||||||
|
|
||||||
QString GdbServerProviderFactory::id() const
|
QString GdbServerProviderFactory::id() const
|
||||||
@@ -410,26 +458,19 @@ HostWidget::HostWidget(QWidget *parent)
|
|||||||
this, &HostWidget::dataChanged);
|
this, &HostWidget::dataChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostWidget::setHost(const QString &host)
|
void HostWidget::setChannel(const QUrl &channel)
|
||||||
{
|
{
|
||||||
const QSignalBlocker blocker(this);
|
const QSignalBlocker blocker(this);
|
||||||
m_hostLineEdit->setText(host);
|
m_hostLineEdit->setText(channel.host());
|
||||||
|
m_portSpinBox->setValue(channel.port());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HostWidget::host() const
|
QUrl HostWidget::channel() const
|
||||||
{
|
{
|
||||||
return m_hostLineEdit->text();
|
QUrl url;
|
||||||
}
|
url.setHost(m_hostLineEdit->text());
|
||||||
|
url.setPort(m_portSpinBox->value());
|
||||||
void HostWidget::setPort(const quint16 &port)
|
return url;
|
||||||
{
|
|
||||||
const QSignalBlocker blocker(this);
|
|
||||||
m_portSpinBox->setValue(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
quint16 HostWidget::port() const
|
|
||||||
{
|
|
||||||
return m_portSpinBox->value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -72,14 +72,13 @@ public:
|
|||||||
QString initCommands() const;
|
QString initCommands() const;
|
||||||
QString resetCommands() const;
|
QString resetCommands() const;
|
||||||
bool useExtendedRemote() const;
|
bool useExtendedRemote() const;
|
||||||
|
QString typeDisplayName() const;
|
||||||
|
|
||||||
virtual bool operator==(const GdbServerProvider &) const;
|
virtual bool operator==(const GdbServerProvider &) const;
|
||||||
|
|
||||||
virtual QString typeDisplayName() const = 0;
|
|
||||||
|
|
||||||
virtual GdbServerProviderConfigWidget *configurationWidget() = 0;
|
virtual GdbServerProviderConfigWidget *configurationWidget() = 0;
|
||||||
|
|
||||||
virtual QString channel() const = 0;
|
virtual QString channelString() const;
|
||||||
virtual GdbServerProvider *clone() const = 0;
|
virtual GdbServerProvider *clone() const = 0;
|
||||||
|
|
||||||
virtual QVariantMap toMap() const;
|
virtual QVariantMap toMap() const;
|
||||||
@@ -92,6 +91,10 @@ public:
|
|||||||
void registerDevice(BareMetalDevice *);
|
void registerDevice(BareMetalDevice *);
|
||||||
void unregisterDevice(BareMetalDevice *);
|
void unregisterDevice(BareMetalDevice *);
|
||||||
|
|
||||||
|
QUrl channel() const;
|
||||||
|
void setChannel(const QUrl &channelString);
|
||||||
|
void setDefaultChannel(const QString &host, int port);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit GdbServerProvider(const QString &id);
|
explicit GdbServerProvider(const QString &id);
|
||||||
explicit GdbServerProvider(const GdbServerProvider &);
|
explicit GdbServerProvider(const GdbServerProvider &);
|
||||||
@@ -100,6 +103,8 @@ protected:
|
|||||||
void setInitCommands(const QString &);
|
void setInitCommands(const QString &);
|
||||||
void setResetCommands(const QString &);
|
void setResetCommands(const QString &);
|
||||||
void setUseExtendedRemote(bool);
|
void setUseExtendedRemote(bool);
|
||||||
|
void setSettingsKeyBase(const QString &settingsBase);
|
||||||
|
void setTypeDisplayName(const QString &typeDisplayName);
|
||||||
|
|
||||||
void providerUpdated();
|
void providerUpdated();
|
||||||
|
|
||||||
@@ -107,7 +112,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
|
QString m_settingsBase;
|
||||||
mutable QString m_displayName;
|
mutable QString m_displayName;
|
||||||
|
QString m_typeDisplayName;
|
||||||
|
QUrl m_channel;
|
||||||
StartupMode m_startupMode = NoStartup;
|
StartupMode m_startupMode = NoStartup;
|
||||||
QString m_initCommands;
|
QString m_initCommands;
|
||||||
QString m_resetCommands;
|
QString m_resetCommands;
|
||||||
@@ -195,10 +203,8 @@ class HostWidget final : public QWidget
|
|||||||
public:
|
public:
|
||||||
explicit HostWidget(QWidget *parent = nullptr);
|
explicit HostWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setHost(const QString &host);
|
void setChannel(const QUrl &host);
|
||||||
QString host() const;
|
QUrl channel() const;
|
||||||
void setPort(const quint16 &port);
|
|
||||||
quint16 port() const;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dataChanged();
|
void dataChanged();
|
||||||
|
@@ -46,8 +46,6 @@ using namespace Utils;
|
|||||||
namespace BareMetal {
|
namespace BareMetal {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
const char hostKeyC[] = "BareMetal.OpenOcdGdbServerProvider.Host";
|
|
||||||
const char portKeyC[] = "BareMetal.OpenOcdGdbServerProvider.Port";
|
|
||||||
const char executableFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ExecutableFile";
|
const char executableFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ExecutableFile";
|
||||||
const char rootScriptsDirKeyC[] = "BareMetal.OpenOcdGdbServerProvider.RootScriptsDir";
|
const char rootScriptsDirKeyC[] = "BareMetal.OpenOcdGdbServerProvider.RootScriptsDir";
|
||||||
const char configurationFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ConfigurationPath";
|
const char configurationFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ConfigurationPath";
|
||||||
@@ -60,11 +58,11 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider()
|
|||||||
{
|
{
|
||||||
setInitCommands(defaultInitCommands());
|
setInitCommands(defaultInitCommands());
|
||||||
setResetCommands(defaultResetCommands());
|
setResetCommands(defaultResetCommands());
|
||||||
|
setDefaultChannel("localhost", 3333);
|
||||||
|
setSettingsKeyBase("BareMetal.OpenOcdGdbServerProvider");
|
||||||
|
setTypeDisplayName(OpenOcdGdbServerProviderFactory::tr("OpenOCD"));
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOcdGdbServerProvider::OpenOcdGdbServerProvider(
|
|
||||||
const OpenOcdGdbServerProvider &other) = default;
|
|
||||||
|
|
||||||
QString OpenOcdGdbServerProvider::defaultInitCommands()
|
QString OpenOcdGdbServerProvider::defaultInitCommands()
|
||||||
{
|
{
|
||||||
return QLatin1String("set remote hardware-breakpoint-limit 6\n"
|
return QLatin1String("set remote hardware-breakpoint-limit 6\n"
|
||||||
@@ -79,19 +77,14 @@ QString OpenOcdGdbServerProvider::defaultResetCommands()
|
|||||||
return QLatin1String("monitor reset halt\n");
|
return QLatin1String("monitor reset halt\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenOcdGdbServerProvider::typeDisplayName() const
|
QString OpenOcdGdbServerProvider::channelString() const
|
||||||
{
|
|
||||||
return OpenOcdGdbServerProviderFactory::tr("OpenOCD");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString OpenOcdGdbServerProvider::channel() const
|
|
||||||
{
|
{
|
||||||
switch (startupMode()) {
|
switch (startupMode()) {
|
||||||
case NoStartup:
|
case NoStartup:
|
||||||
// fallback
|
// fallback
|
||||||
case StartupOnNetwork:
|
case StartupOnNetwork:
|
||||||
// Just return as "host:port" form.
|
// Just return as "host:port" form.
|
||||||
return m_host + QLatin1Char(':') + QString::number(m_port);
|
return GdbServerProvider::channelString();
|
||||||
case StartupOnPipe: {
|
case StartupOnPipe: {
|
||||||
// In the pipe mode need to add quotes to each item of arguments;
|
// In the pipe mode need to add quotes to each item of arguments;
|
||||||
// otherwise running will be stuck.
|
// otherwise running will be stuck.
|
||||||
@@ -118,7 +111,7 @@ CommandLine OpenOcdGdbServerProvider::command() const
|
|||||||
if (startupMode() == StartupOnPipe)
|
if (startupMode() == StartupOnPipe)
|
||||||
cmd.addArg("gdb_port pipe");
|
cmd.addArg("gdb_port pipe");
|
||||||
else
|
else
|
||||||
cmd.addArg("gdb_port " + QString::number(m_port));
|
cmd.addArg("gdb_port " + QString::number(channel().port()));
|
||||||
|
|
||||||
if (!m_rootScriptsDir.isEmpty())
|
if (!m_rootScriptsDir.isEmpty())
|
||||||
cmd.addArgs({"-s", m_rootScriptsDir});
|
cmd.addArgs({"-s", m_rootScriptsDir});
|
||||||
@@ -145,7 +138,7 @@ bool OpenOcdGdbServerProvider::isValid() const
|
|||||||
const StartupMode m = startupMode();
|
const StartupMode m = startupMode();
|
||||||
|
|
||||||
if (m == NoStartup || m == StartupOnNetwork) {
|
if (m == NoStartup || m == StartupOnNetwork) {
|
||||||
if (m_host.isEmpty())
|
if (channel().host().isEmpty())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +158,6 @@ GdbServerProvider *OpenOcdGdbServerProvider::clone() const
|
|||||||
QVariantMap OpenOcdGdbServerProvider::toMap() const
|
QVariantMap OpenOcdGdbServerProvider::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap data = GdbServerProvider::toMap();
|
QVariantMap data = GdbServerProvider::toMap();
|
||||||
data.insert(QLatin1String(hostKeyC), m_host);
|
|
||||||
data.insert(QLatin1String(portKeyC), m_port);
|
|
||||||
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
|
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
|
||||||
data.insert(QLatin1String(rootScriptsDirKeyC), m_rootScriptsDir);
|
data.insert(QLatin1String(rootScriptsDirKeyC), m_rootScriptsDir);
|
||||||
data.insert(QLatin1String(configurationFileKeyC), m_configurationFile);
|
data.insert(QLatin1String(configurationFileKeyC), m_configurationFile);
|
||||||
@@ -179,8 +170,6 @@ bool OpenOcdGdbServerProvider::fromMap(const QVariantMap &data)
|
|||||||
if (!GdbServerProvider::fromMap(data))
|
if (!GdbServerProvider::fromMap(data))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_host = data.value(QLatin1String(hostKeyC)).toString();
|
|
||||||
m_port = data.value(QLatin1String(portKeyC)).toInt();
|
|
||||||
m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
|
m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
|
||||||
m_rootScriptsDir = data.value(QLatin1String(rootScriptsDirKeyC)).toString();
|
m_rootScriptsDir = data.value(QLatin1String(rootScriptsDirKeyC)).toString();
|
||||||
m_configurationFile = data.value(QLatin1String(configurationFileKeyC)).toString();
|
m_configurationFile = data.value(QLatin1String(configurationFileKeyC)).toString();
|
||||||
@@ -194,9 +183,7 @@ bool OpenOcdGdbServerProvider::operator==(const GdbServerProvider &other) const
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto p = static_cast<const OpenOcdGdbServerProvider *>(&other);
|
const auto p = static_cast<const OpenOcdGdbServerProvider *>(&other);
|
||||||
return m_host == p->m_host
|
return m_executableFile == p->m_executableFile
|
||||||
&& m_port == p->m_port
|
|
||||||
&& m_executableFile == p->m_executableFile
|
|
||||||
&& m_rootScriptsDir == p->m_rootScriptsDir
|
&& m_rootScriptsDir == p->m_rootScriptsDir
|
||||||
&& m_configurationFile == p->m_configurationFile
|
&& m_configurationFile == p->m_configurationFile
|
||||||
&& m_additionalArguments == p->m_additionalArguments;
|
&& m_additionalArguments == p->m_additionalArguments;
|
||||||
@@ -320,8 +307,7 @@ void OpenOcdGdbServerProviderConfigWidget::applyImpl()
|
|||||||
const auto p = static_cast<OpenOcdGdbServerProvider *>(provider());
|
const auto p = static_cast<OpenOcdGdbServerProvider *>(provider());
|
||||||
Q_ASSERT(p);
|
Q_ASSERT(p);
|
||||||
|
|
||||||
p->m_host = m_hostWidget->host();
|
p->setChannel(m_hostWidget->channel());
|
||||||
p->m_port = m_hostWidget->port();
|
|
||||||
p->m_executableFile = m_executableFileChooser->fileName();
|
p->m_executableFile = m_executableFileChooser->fileName();
|
||||||
p->m_rootScriptsDir = m_rootScriptsDirChooser->fileName().toString();
|
p->m_rootScriptsDir = m_rootScriptsDirChooser->fileName().toString();
|
||||||
p->m_configurationFile = m_configurationFileChooser->fileName().toString();
|
p->m_configurationFile = m_configurationFileChooser->fileName().toString();
|
||||||
@@ -342,8 +328,7 @@ void OpenOcdGdbServerProviderConfigWidget::setFromProvider()
|
|||||||
|
|
||||||
const QSignalBlocker blocker(this);
|
const QSignalBlocker blocker(this);
|
||||||
startupModeChanged();
|
startupModeChanged();
|
||||||
m_hostWidget->setHost(p->m_host);
|
m_hostWidget->setChannel(p->channel());
|
||||||
m_hostWidget->setPort(p->m_port);
|
|
||||||
m_executableFileChooser->setFileName(p->m_executableFile);
|
m_executableFileChooser->setFileName(p->m_executableFile);
|
||||||
m_rootScriptsDirChooser->setFileName(Utils::FilePath::fromString(p->m_rootScriptsDir));
|
m_rootScriptsDirChooser->setFileName(Utils::FilePath::fromString(p->m_rootScriptsDir));
|
||||||
m_configurationFileChooser->setFileName(Utils::FilePath::fromString(p->m_configurationFile));
|
m_configurationFileChooser->setFileName(Utils::FilePath::fromString(p->m_configurationFile));
|
||||||
|
@@ -40,8 +40,6 @@ class OpenOcdGdbServerProviderFactory;
|
|||||||
class OpenOcdGdbServerProvider final : public GdbServerProvider
|
class OpenOcdGdbServerProvider final : public GdbServerProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString typeDisplayName() const final;
|
|
||||||
|
|
||||||
QVariantMap toMap() const final;
|
QVariantMap toMap() const final;
|
||||||
bool fromMap(const QVariantMap &data) final;
|
bool fromMap(const QVariantMap &data) final;
|
||||||
|
|
||||||
@@ -50,7 +48,7 @@ public:
|
|||||||
GdbServerProviderConfigWidget *configurationWidget() final;
|
GdbServerProviderConfigWidget *configurationWidget() final;
|
||||||
GdbServerProvider *clone() const final;
|
GdbServerProvider *clone() const final;
|
||||||
|
|
||||||
QString channel() const final;
|
QString channelString() const final;
|
||||||
Utils::CommandLine command() const final;
|
Utils::CommandLine command() const final;
|
||||||
|
|
||||||
bool canStartupMode(StartupMode mode) const final;
|
bool canStartupMode(StartupMode mode) const final;
|
||||||
@@ -58,13 +56,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
explicit OpenOcdGdbServerProvider();
|
explicit OpenOcdGdbServerProvider();
|
||||||
explicit OpenOcdGdbServerProvider(const OpenOcdGdbServerProvider &);
|
|
||||||
|
|
||||||
static QString defaultInitCommands();
|
static QString defaultInitCommands();
|
||||||
static QString defaultResetCommands();
|
static QString defaultResetCommands();
|
||||||
|
|
||||||
QString m_host = QLatin1String("localhost");
|
|
||||||
quint16 m_port = 3333;
|
|
||||||
Utils::FilePath m_executableFile = Utils::FilePath::fromString("openocd");
|
Utils::FilePath m_executableFile = Utils::FilePath::fromString("openocd");
|
||||||
QString m_rootScriptsDir;
|
QString m_rootScriptsDir;
|
||||||
QString m_configurationFile;
|
QString m_configurationFile;
|
||||||
|
@@ -47,8 +47,6 @@ using namespace Utils;
|
|||||||
namespace BareMetal {
|
namespace BareMetal {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
const char hostKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.Host";
|
|
||||||
const char portKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.Port";
|
|
||||||
const char executableFileKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExecutableFile";
|
const char executableFileKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExecutableFile";
|
||||||
const char verboseLevelKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.VerboseLevel";
|
const char verboseLevelKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.VerboseLevel";
|
||||||
const char extendedModeKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExtendedMode";
|
const char extendedModeKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExtendedMode";
|
||||||
@@ -62,13 +60,14 @@ StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider()
|
|||||||
{
|
{
|
||||||
setInitCommands(defaultInitCommands());
|
setInitCommands(defaultInitCommands());
|
||||||
setResetCommands(defaultResetCommands());
|
setResetCommands(defaultResetCommands());
|
||||||
|
setDefaultChannel("localhost", 4242);
|
||||||
|
setSettingsKeyBase("BareMetal.StLinkUtilGdbServerProvider");
|
||||||
|
setTypeDisplayName(StLinkUtilGdbServerProviderFactory::tr("ST-LINK Utility"));
|
||||||
}
|
}
|
||||||
|
|
||||||
StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider(
|
StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider(
|
||||||
const StLinkUtilGdbServerProvider &other)
|
const StLinkUtilGdbServerProvider &other)
|
||||||
: GdbServerProvider(other)
|
: GdbServerProvider(other)
|
||||||
, m_host(other.m_host)
|
|
||||||
, m_port(other.m_port)
|
|
||||||
, m_executableFile(other.m_executableFile)
|
, m_executableFile(other.m_executableFile)
|
||||||
, m_verboseLevel(0)
|
, m_verboseLevel(0)
|
||||||
, m_extendedMode(false)
|
, m_extendedMode(false)
|
||||||
@@ -87,19 +86,14 @@ QString StLinkUtilGdbServerProvider::defaultResetCommands()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StLinkUtilGdbServerProvider::typeDisplayName() const
|
QString StLinkUtilGdbServerProvider::channelString() const
|
||||||
{
|
|
||||||
return StLinkUtilGdbServerProviderFactory::tr("ST-LINK Utility");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString StLinkUtilGdbServerProvider::channel() const
|
|
||||||
{
|
{
|
||||||
switch (startupMode()) {
|
switch (startupMode()) {
|
||||||
case NoStartup:
|
case NoStartup:
|
||||||
// fallback
|
// fallback
|
||||||
case StartupOnNetwork:
|
case StartupOnNetwork:
|
||||||
// Just return as "host:port" form.
|
// Just return as "host:port" form.
|
||||||
return m_host + QLatin1Char(':') + QString::number(m_port);
|
return GdbServerProvider::channelString();
|
||||||
case StartupOnPipe:
|
case StartupOnPipe:
|
||||||
// Unsupported mode
|
// Unsupported mode
|
||||||
return {};
|
return {};
|
||||||
@@ -119,7 +113,7 @@ CommandLine StLinkUtilGdbServerProvider::command() const
|
|||||||
cmd.addArg("--no-reset");
|
cmd.addArg("--no-reset");
|
||||||
|
|
||||||
cmd.addArg("--stlink_version=" + QString::number(m_transport));
|
cmd.addArg("--stlink_version=" + QString::number(m_transport));
|
||||||
cmd.addArg("--listen_port=" + QString::number(m_port));
|
cmd.addArg("--listen_port=" + QString::number(channel().port()));
|
||||||
cmd.addArg("--verbose=" + QString::number(m_verboseLevel));
|
cmd.addArg("--verbose=" + QString::number(m_verboseLevel));
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -138,7 +132,7 @@ bool StLinkUtilGdbServerProvider::isValid() const
|
|||||||
const StartupMode m = startupMode();
|
const StartupMode m = startupMode();
|
||||||
|
|
||||||
if (m == NoStartup || m == StartupOnNetwork) {
|
if (m == NoStartup || m == StartupOnNetwork) {
|
||||||
if (m_host.isEmpty())
|
if (channel().host().isEmpty())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +152,6 @@ GdbServerProvider *StLinkUtilGdbServerProvider::clone() const
|
|||||||
QVariantMap StLinkUtilGdbServerProvider::toMap() const
|
QVariantMap StLinkUtilGdbServerProvider::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap data = GdbServerProvider::toMap();
|
QVariantMap data = GdbServerProvider::toMap();
|
||||||
data.insert(QLatin1String(hostKeyC), m_host);
|
|
||||||
data.insert(QLatin1String(portKeyC), m_port);
|
|
||||||
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
|
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
|
||||||
data.insert(QLatin1String(verboseLevelKeyC), m_verboseLevel);
|
data.insert(QLatin1String(verboseLevelKeyC), m_verboseLevel);
|
||||||
data.insert(QLatin1String(extendedModeKeyC), m_extendedMode);
|
data.insert(QLatin1String(extendedModeKeyC), m_extendedMode);
|
||||||
@@ -173,8 +165,6 @@ bool StLinkUtilGdbServerProvider::fromMap(const QVariantMap &data)
|
|||||||
if (!GdbServerProvider::fromMap(data))
|
if (!GdbServerProvider::fromMap(data))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_host = data.value(QLatin1String(hostKeyC)).toString();
|
|
||||||
m_port = data.value(QLatin1String(portKeyC)).toInt();
|
|
||||||
m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
|
m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
|
||||||
m_verboseLevel = data.value(QLatin1String(verboseLevelKeyC)).toInt();
|
m_verboseLevel = data.value(QLatin1String(verboseLevelKeyC)).toInt();
|
||||||
m_extendedMode = data.value(QLatin1String(extendedModeKeyC)).toBool();
|
m_extendedMode = data.value(QLatin1String(extendedModeKeyC)).toBool();
|
||||||
@@ -190,9 +180,7 @@ bool StLinkUtilGdbServerProvider::operator==(const GdbServerProvider &other) con
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto p = static_cast<const StLinkUtilGdbServerProvider *>(&other);
|
const auto p = static_cast<const StLinkUtilGdbServerProvider *>(&other);
|
||||||
return m_host == p->m_host
|
return m_executableFile == p->m_executableFile
|
||||||
&& m_port == p->m_port
|
|
||||||
&& m_executableFile == p->m_executableFile
|
|
||||||
&& m_verboseLevel == p->m_verboseLevel
|
&& m_verboseLevel == p->m_verboseLevel
|
||||||
&& m_extendedMode == p->m_extendedMode
|
&& m_extendedMode == p->m_extendedMode
|
||||||
&& m_resetBoard == p->m_resetBoard
|
&& m_resetBoard == p->m_resetBoard
|
||||||
@@ -329,8 +317,7 @@ void StLinkUtilGdbServerProviderConfigWidget::applyImpl()
|
|||||||
const auto p = static_cast<StLinkUtilGdbServerProvider *>(provider());
|
const auto p = static_cast<StLinkUtilGdbServerProvider *>(provider());
|
||||||
Q_ASSERT(p);
|
Q_ASSERT(p);
|
||||||
|
|
||||||
p->m_host = m_hostWidget->host();
|
p->setChannel(m_hostWidget->channel());
|
||||||
p->m_port = m_hostWidget->port();
|
|
||||||
p->m_executableFile = m_executableFileChooser->fileName();
|
p->m_executableFile = m_executableFileChooser->fileName();
|
||||||
p->m_verboseLevel = m_verboseLevelSpinBox->value();
|
p->m_verboseLevel = m_verboseLevelSpinBox->value();
|
||||||
p->m_extendedMode = m_extendedModeCheckBox->isChecked();
|
p->m_extendedMode = m_extendedModeCheckBox->isChecked();
|
||||||
@@ -387,8 +374,7 @@ void StLinkUtilGdbServerProviderConfigWidget::setFromProvider()
|
|||||||
|
|
||||||
const QSignalBlocker blocker(this);
|
const QSignalBlocker blocker(this);
|
||||||
startupModeChanged();
|
startupModeChanged();
|
||||||
m_hostWidget->setHost(p->m_host);
|
m_hostWidget->setChannel(p->channel());
|
||||||
m_hostWidget->setPort(p->m_port);
|
|
||||||
m_executableFileChooser->setFileName(p->m_executableFile);
|
m_executableFileChooser->setFileName(p->m_executableFile);
|
||||||
m_verboseLevelSpinBox->setValue(p->m_verboseLevel);
|
m_verboseLevelSpinBox->setValue(p->m_verboseLevel);
|
||||||
m_extendedModeCheckBox->setChecked(p->m_extendedMode);
|
m_extendedModeCheckBox->setChecked(p->m_extendedMode);
|
||||||
|
@@ -45,7 +45,6 @@ class StLinkUtilGdbServerProvider final : public GdbServerProvider
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum TransportLayer { ScsiOverUsb = 1, RawUsb = 2 };
|
enum TransportLayer { ScsiOverUsb = 1, RawUsb = 2 };
|
||||||
QString typeDisplayName() const final;
|
|
||||||
|
|
||||||
QVariantMap toMap() const final;
|
QVariantMap toMap() const final;
|
||||||
bool fromMap(const QVariantMap &data) final;
|
bool fromMap(const QVariantMap &data) final;
|
||||||
@@ -55,7 +54,7 @@ public:
|
|||||||
GdbServerProviderConfigWidget *configurationWidget() final;
|
GdbServerProviderConfigWidget *configurationWidget() final;
|
||||||
GdbServerProvider *clone() const final;
|
GdbServerProvider *clone() const final;
|
||||||
|
|
||||||
QString channel() const final;
|
QString channelString() const final;
|
||||||
Utils::CommandLine command() const final;
|
Utils::CommandLine command() const final;
|
||||||
|
|
||||||
bool canStartupMode(StartupMode mode) const final;
|
bool canStartupMode(StartupMode mode) const final;
|
||||||
@@ -68,8 +67,6 @@ private:
|
|||||||
static QString defaultInitCommands();
|
static QString defaultInitCommands();
|
||||||
static QString defaultResetCommands();
|
static QString defaultResetCommands();
|
||||||
|
|
||||||
QString m_host = QLatin1String("localhost");
|
|
||||||
quint16 m_port = 4242;
|
|
||||||
Utils::FilePath m_executableFile = Utils::FilePath::fromString("st-util");
|
Utils::FilePath m_executableFile = Utils::FilePath::fromString("st-util");
|
||||||
int m_verboseLevel = 0; // 0..99
|
int m_verboseLevel = 0; // 0..99
|
||||||
bool m_extendedMode = false; // Listening for connections after disconnect
|
bool m_extendedMode = false; // Listening for connections after disconnect
|
||||||
|
Reference in New Issue
Block a user