--- /dev/null
+//
+// commandprocessor.cpp: Command processor
+//
+// Part of the Architektonas Project
+// (C) 2021 Underground Software
+// See the README and GPLv3 files for licensing and warranty information
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 12/16/2021 Created this file
+//
+
+#include "commandprocessor.h"
+#include "structs.h"
+
+CommandProcessor::CommandProcessor()
+{
+}
+
+CommandProcessor::~CommandProcessor()
+{
+}
+
+void CommandProcessor::Error(QString s)
+{
+ AddToResponse("Error", "red", s);
+ parseError = true;
+}
+
+void CommandProcessor::Warning(QString s)
+{
+ AddToResponse("Warning", "orange", s);
+}
+
+void CommandProcessor::AddToResponse(QString type, QString c, QString msg)
+{
+ if (response.length() > 0)
+ response += "<br>";
+
+ response += QString("<font color=%2>%3: %1</font>").arg(msg).arg(c).arg(type);
+}
+
+void CommandProcessor::ClearWhitespace(QString & s)
+{
+ while (s.length() > 0)
+ {
+ if (s[0].isSpace() == false)
+ return;
+
+ s.remove(0, 1);
+ }
+}
+
+double CommandProcessor::GetDouble(QString & s)
+{
+/*
+N.B.: Still need to add parsing of fractional components, if any (nn/nn)
+*/
+ QString n;
+ bool ok;
+ parseError = false;
+ missingParam = false;
+
+ ClearWhitespace(s);
+
+ while (s.length() > 0)
+ {
+ if ((s[0].isNumber() == false) && (s[0] != QChar('.')) && (s[0] != QChar('+')) && (s[0] != QChar('-')) && (s[0] != QChar('e')))
+ break;
+
+ n.push_back(s[0]);
+ s.remove(0, 1);
+ }
+
+ if (n.length() == 0)
+ {
+ missingParam = true;
+ return 0;
+ }
+
+ double d = n.toDouble(&ok);
+
+ if (!ok)
+ Error(QString("could not parse number '%1'").arg(n));
+
+ return d;
+}
+
+int CommandProcessor::GetInt(QString & s)
+{
+ QString n;
+ bool ok;
+ parseError = false;
+ missingParam = false;
+
+ ClearWhitespace(s);
+
+ while (s.length() > 0)
+ {
+ if (s[0].isNumber() == false)
+ break;
+
+ n.push_back(s[0]);
+ s.remove(0, 1);
+ }
+
+ if (n.size() == 0)
+ {
+ missingParam = true;
+ return 0;
+ }
+
+ int i = n.toInt(&ok);
+
+ if (!ok)
+ Error(QString("could not parse number '%1'").arg(n));
+
+ return i;
+}
+
+QString CommandProcessor::GetString(QString & s)
+{
+ QString r;
+
+ ClearWhitespace(s);
+
+ while (s.length() > 0)
+ {
+ if (s[0].isLetter() == false)
+ break;
+
+ r.push_back(s[0]);
+ s.remove(0, 1);
+ }
+
+ return r;
+}
+
+int CommandProcessor::GetUnits(QString & s)
+{
+ parseError = false;
+ missingParam = false;
+ QString unit = GetString(s);
+
+ if (unit.length() == 0)
+ {
+ missingParam = true;
+ return BUInch;
+ }
+
+ BasicUnit bu = BUInch;
+
+ if (unit == QString("inch") || unit == QString("in"))
+ {
+ bu = BUInch;
+ }
+ else if (unit == QString("foot") || unit == QString("ft"))
+ {
+ bu = BUFoot;
+ }
+ else if (unit == QString("yard") || unit == QString("yd"))
+ {
+ bu = BUYard;
+ }
+ else
+ {
+ Error(QString("bad unit '%1'").arg(unit));
+ }
+
+ return bu;
+}
+
+bool CommandProcessor::GetComma(QString & s)
+{
+ ClearWhitespace(s);
+
+ if ((s.length() > 0) && (s[0] == QChar(',')))
+ {
+ s.remove(0, 1);
+ return true;
+ }
+
+ return false;
+}
+
+QString CommandProcessor::Process(QString cmd)
+{
+ response.clear();
+ cmd = cmd.toLower();
+
+ if (Global::tool == TTParallel)
+ {
+ response += QString("Parallel: %1").arg(cmd);
+ bool goodDist = false, goodNum = false, goodBU = false;
+
+ double d = GetDouble(cmd);
+ int i = 0;
+ int bu = 0;
+
+ if (!missingParam && !parseError)
+ {
+ goodDist = true;
+ bu = GetUnits(cmd);
+
+ if (!missingParam && !parseError)
+ goodBU = true;
+ }
+
+ if (!parseError)
+ {
+ if (GetComma(cmd) == false)
+ {
+ ClearWhitespace(cmd);
+
+ if (cmd.length() > 0)
+ Error("missing comma");
+ }
+ else
+ {
+ i = GetInt(cmd);
+
+ if (!missingParam && !parseError)
+ {
+ goodNum = true;
+
+ ClearWhitespace(cmd);
+
+ if (cmd.length() > 0)
+ Warning(QString("extra junk '%1' at end ignored").arg(cmd));
+ }
+ }
+ }
+
+ if (!parseError)
+ {
+ if (goodBU)
+ Global::parallelBU = bu;
+
+ if (goodDist)
+ Global::parallelDist = d * buInInches[Global::parallelBU];
+
+ if (goodNum)
+ Global::parallelNum = i;
+
+ emit(UpdateNeeded());
+ }
+ }
+ else
+ {
+ Error(QString("don't know how to '%1'").arg(cmd));
+ }
+
+ return response;
+}