Add support for configuring an external SPIR-V disassembler in Qt UI

This commit is contained in:
baldurk
2017-02-16 17:10:04 +00:00
parent 11a914bd59
commit 3398fcc9de
9 changed files with 316 additions and 122 deletions
+26 -40
View File
@@ -39,6 +39,16 @@ variantType convertToVariant(const origType &val)
return variantType(val);
}
template <typename variantType, typename innerType>
variantType convertToVariant(const QList<innerType> &val)
{
variantType ret;
ret.reserve(val.count());
for(const innerType &s : val)
ret.push_back(s);
return ret;
}
template <>
QVariantMap convertToVariant(const QStringMap &val)
{
@@ -50,32 +60,28 @@ QVariantMap convertToVariant(const QStringMap &val)
return ret;
}
template <>
QVariantList convertToVariant(const QList<QString> &val)
{
QVariantList ret;
ret.reserve(val.count());
for(const QString &s : val)
ret.push_back(s);
return ret;
}
template <>
QVariantList convertToVariant(const QList<RemoteHost> &val)
{
QVariantList ret;
ret.reserve(val.count());
for(const RemoteHost &s : val)
ret.push_back(s);
return ret;
}
template <typename origType, typename variantType>
origType convertFromVariant(const variantType &val)
{
return origType(val);
}
template <>
QString convertFromVariant(const QVariant &val)
{
return val.toString();
}
template <typename listType>
listType convertFromVariant(const QList<QVariant> &val)
{
listType ret;
ret.reserve(val.count());
for(const QVariant &s : val)
ret.push_back(convertFromVariant<decltype(ret.value(0))>(s));
return ret;
}
template <>
QStringMap convertFromVariant(const QVariantMap &val)
{
@@ -87,26 +93,6 @@ QStringMap convertFromVariant(const QVariantMap &val)
return ret;
}
template <>
QList<QString> convertFromVariant(const QVariantList &val)
{
QList<QString> ret;
ret.reserve(val.count());
for(const QVariant &s : val)
ret.push_back(s.toString());
return ret;
}
template <>
QList<RemoteHost> convertFromVariant(const QVariantList &val)
{
QList<RemoteHost> ret;
ret.reserve(val.count());
for(const QVariant &s : val)
ret.push_back(RemoteHost(s));
return ret;
}
bool PersistantConfig::Deserialize(const QString &filename)
{
QFile f(filename);
+32
View File
@@ -33,6 +33,36 @@
typedef QMap<QString, QString> QStringMap;
struct SPIRVDisassembler
{
SPIRVDisassembler() {}
SPIRVDisassembler(const QVariant &var)
{
QVariantMap map = var.toMap();
if(map.contains("name"))
name = map["name"].toString();
if(map.contains("executable"))
executable = map["executable"].toString();
if(map.contains("args"))
args = map["args"].toString();
}
operator QVariant() const
{
QVariantMap map;
map["name"] = name;
map["executable"] = executable;
map["args"] = args;
return map;
}
QString name;
QString executable;
QString args;
};
#define CONFIG_SETTING_VAL(access, variantType, type, name, defaultValue) \
access: \
type name = defaultValue;
@@ -108,6 +138,8 @@ typedef QMap<QString, QString> QStringMap;
\
CONFIG_SETTING_VAL(public, bool, bool, AllowGlobalHook, false) \
\
CONFIG_SETTING(public, QVariantList, QList<SPIRVDisassembler>, SPIRVDisassemblers) \
\
CONFIG_SETTING(private, QVariantMap, QStringMap, ConfigSettings) \
\
CONFIG_SETTING(private, QVariantList, QList<RemoteHost>, RemoteHostList)
+97
View File
@@ -807,6 +807,103 @@ bool RunProcessAsAdmin(const QString &fullExecutablePath, const QStringList &par
#endif
}
QStringList ParseArgsList(const QString &args)
{
QStringList ret;
if(args.isEmpty())
return ret;
// on windows just use the function provided by the system
#if defined(Q_OS_WIN32)
std::wstring wargs = args.toStdWString();
int argc = 0;
wchar_t **argv = CommandLineToArgvW(wargs.c_str(), &argc);
for(int i = 0; i < argc; i++)
ret << QString::fromWCharArray(argv[i]);
LocalFree(argv);
#else
std::string argString = args.toStdString();
// perform some kind of sane parsing
bool dquot = false, squot = false; // are we inside ''s or ""s
// current character
char *c = &argString[0];
// current argument we're building
std::string a;
while(*c)
{
if(!dquot && !squot && (*c == ' ' || *c == '\t'))
{
if(!a.empty())
ret << QString::fromStdString(a);
a = "";
}
else if(!dquot && *c == '"')
{
dquot = true;
}
else if(!squot && *c == '\'')
{
squot = true;
}
else if(dquot && *c == '"')
{
dquot = false;
}
else if(squot && *c == '\'')
{
squot = false;
}
else if(squot)
{
// single quotes don't escape, just copy literally until we leave single quote mode
a.push_back(*c);
}
else if(dquot)
{
// handle escaping
if(*c == '\\')
{
c++;
if(*c)
{
a.push_back(*c);
}
else
{
qCritical() << "Malformed args list:" << args;
return ret;
}
}
else
{
a.push_back(*c);
}
}
else
{
a.push_back(*c);
}
c++;
}
// if we were building an argument when we hit the end of the string
if(!a.empty())
ret << QString::fromStdString(a);
#endif
return ret;
}
void ShowProgressDialog(QWidget *window, const QString &labelText, ProgressFinishedMethod finished,
ProgressUpdateMethod update)
{
+1
View File
@@ -687,6 +687,7 @@ class QProgressDialog;
typedef std::function<float()> ProgressUpdateMethod;
typedef std::function<bool()> ProgressFinishedMethod;
QStringList ParseArgsList(const QString &args);
bool RunProcessAsAdmin(const QString &fullExecutablePath, const QStringList &params,
std::function<void()> finishedCallback = std::function<void()>());