2017-02-19 14:59:39 -08:00
|
|
|
#include "LauncherArgumentTokenizer.hxx"
|
|
|
|
|
2017-12-15 15:42:36 +00:00
|
|
|
#include <QVariantMap>
|
|
|
|
#include <QJSEngine>
|
|
|
|
|
2017-02-19 14:59:39 -08:00
|
|
|
LauncherArgumentTokenizer::LauncherArgumentTokenizer()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-12-15 15:42:36 +00:00
|
|
|
QList<ArgumentToken> LauncherArgumentTokenizer::tokenize(QString in) const
|
2017-02-19 14:59:39 -08:00
|
|
|
{
|
|
|
|
int index = 0;
|
|
|
|
const int len = in.count();
|
|
|
|
QChar c, nc;
|
|
|
|
State state = Start;
|
|
|
|
QString key, value;
|
2017-12-15 15:42:36 +00:00
|
|
|
QList<ArgumentToken> result;
|
2017-02-19 14:59:39 -08:00
|
|
|
|
|
|
|
for (; index < len; ++index) {
|
|
|
|
c = in.at(index);
|
|
|
|
nc = index < (len - 1) ? in.at(index + 1) : QChar();
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case Start:
|
|
|
|
if (c == QChar('-')) {
|
|
|
|
if (nc == QChar('-')) {
|
|
|
|
state = Key;
|
|
|
|
key.clear();
|
|
|
|
++index;
|
|
|
|
} else {
|
|
|
|
// should we pemit single hyphen arguments?
|
|
|
|
// choosing to fail for now
|
2017-12-15 15:42:36 +00:00
|
|
|
return {};
|
2017-02-19 14:59:39 -08:00
|
|
|
}
|
|
|
|
} else if (c == QChar('#')) {
|
|
|
|
state = Comment;
|
|
|
|
break;
|
|
|
|
} else if (c.isSpace()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Key:
|
|
|
|
if (c == QChar('=')) {
|
|
|
|
state = Value;
|
|
|
|
value.clear();
|
|
|
|
} else if (c.isSpace()) {
|
|
|
|
state = Start;
|
2017-12-15 15:42:36 +00:00
|
|
|
result.append(ArgumentToken{key});
|
2017-02-19 14:59:39 -08:00
|
|
|
} else {
|
|
|
|
// could check for illegal charatcers here
|
|
|
|
key.append(c);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Value:
|
|
|
|
if (c == QChar('"')) {
|
|
|
|
state = Quoted;
|
|
|
|
} else if (c.isSpace()) {
|
|
|
|
state = Start;
|
2017-12-15 15:42:36 +00:00
|
|
|
result.append(ArgumentToken{key, value});
|
2017-02-19 14:59:39 -08:00
|
|
|
} else {
|
|
|
|
value.append(c);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Quoted:
|
|
|
|
if (c == QChar('\\')) {
|
|
|
|
// check for escaped double-quote inside quoted value
|
|
|
|
if (nc == QChar('"')) {
|
|
|
|
++index;
|
2017-07-25 10:00:19 +01:00
|
|
|
} else {
|
|
|
|
value.append(c); // normal '\' inside quoted
|
2017-02-19 14:59:39 -08:00
|
|
|
}
|
|
|
|
} else if (c == QChar('"')) {
|
|
|
|
state = Value;
|
|
|
|
} else {
|
|
|
|
value.append(c);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Comment:
|
|
|
|
if ((c == QChar('\n')) || (c == QChar('\r'))) {
|
|
|
|
state = Start;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// nothing to do, eat comment chars
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
} // of state switch
|
|
|
|
} // of character loop
|
|
|
|
|
|
|
|
// ensure last argument isn't lost
|
|
|
|
if (state == Key) {
|
2017-12-15 15:42:36 +00:00
|
|
|
result.append(ArgumentToken{key});
|
2017-02-19 14:59:39 -08:00
|
|
|
} else if (state == Value) {
|
2017-12-15 15:42:36 +00:00
|
|
|
result.append(ArgumentToken{key, value});
|
2017-02-19 14:59:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2017-12-15 15:42:36 +00:00
|
|
|
|
|
|
|
QVariantList LauncherArgumentTokenizer::tokens() const
|
|
|
|
{
|
|
|
|
QVariantList result;
|
|
|
|
Q_FOREACH(auto tk, tokenize(m_argString)) {
|
|
|
|
QVariantMap m;
|
|
|
|
m["arg"] = tk.arg;
|
|
|
|
m["value"] = tk.value;
|
|
|
|
result.append(m);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherArgumentTokenizer::setArgString(QString argString)
|
|
|
|
{
|
|
|
|
if (m_argString == argString)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_argString = argString;
|
|
|
|
emit argStringChanged(m_argString);
|
|
|
|
}
|