]> Shamusworld >> Repos - architektonas/blob - src/commandprocessor.cpp
Added Parallel tool + command processing.
[architektonas] / src / commandprocessor.cpp
1 //
2 // commandprocessor.cpp: Command processor
3 //
4 // Part of the Architektonas Project
5 // (C) 2021 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
7 //
8 // JLH = James Hammons <jlhamm@acm.org>
9 //
10 // WHO  WHEN        WHAT
11 // ---  ----------  ------------------------------------------------------------
12 // JLH  12/16/2021  Created this file
13 //
14
15 #include "commandprocessor.h"
16 #include "structs.h"
17
18 CommandProcessor::CommandProcessor()
19 {
20 }
21
22 CommandProcessor::~CommandProcessor()
23 {
24 }
25
26 void CommandProcessor::Error(QString s)
27 {
28         AddToResponse("Error", "red", s);
29         parseError = true;
30 }
31
32 void CommandProcessor::Warning(QString s)
33 {
34         AddToResponse("Warning", "orange", s);
35 }
36
37 void CommandProcessor::AddToResponse(QString type, QString c, QString msg)
38 {
39         if (response.length() > 0)
40                 response += "<br>";
41
42         response += QString("<font color=%2>%3: %1</font>").arg(msg).arg(c).arg(type);
43 }
44
45 void CommandProcessor::ClearWhitespace(QString & s)
46 {
47         while (s.length() > 0)
48         {
49                 if (s[0].isSpace() == false)
50                         return;
51
52                 s.remove(0, 1);
53         }
54 }
55
56 double CommandProcessor::GetDouble(QString & s)
57 {
58 /*
59 N.B.: Still need to add parsing of fractional components, if any (nn/nn)
60 */
61         QString n;
62         bool ok;
63         parseError = false;
64         missingParam = false;
65
66         ClearWhitespace(s);
67
68         while (s.length() > 0)
69         {
70                 if ((s[0].isNumber() == false) && (s[0] != QChar('.')) && (s[0] != QChar('+')) && (s[0] != QChar('-')) && (s[0] != QChar('e')))
71                         break;
72
73                 n.push_back(s[0]);
74                 s.remove(0, 1);
75         }
76
77         if (n.length() == 0)
78         {
79                 missingParam = true;
80                 return 0;
81         }
82
83         double d = n.toDouble(&ok);
84
85         if (!ok)
86                 Error(QString("could not parse number '%1'").arg(n));
87
88         return d;
89 }
90
91 int CommandProcessor::GetInt(QString & s)
92 {
93         QString n;
94         bool ok;
95         parseError = false;
96         missingParam = false;
97
98         ClearWhitespace(s);
99
100         while (s.length() > 0)
101         {
102                 if (s[0].isNumber() == false)
103                         break;
104
105                 n.push_back(s[0]);
106                 s.remove(0, 1);
107         }
108
109         if (n.size() == 0)
110         {
111                 missingParam = true;
112                 return 0;
113         }
114
115         int i = n.toInt(&ok);
116
117         if (!ok)
118                 Error(QString("could not parse number '%1'").arg(n));
119
120         return i;
121 }
122
123 QString CommandProcessor::GetString(QString & s)
124 {
125         QString r;
126
127         ClearWhitespace(s);
128
129         while (s.length() > 0)
130         {
131                 if (s[0].isLetter() == false)
132                         break;
133
134                 r.push_back(s[0]);
135                 s.remove(0, 1);
136         }
137
138         return r;
139 }
140
141 int CommandProcessor::GetUnits(QString & s)
142 {
143         parseError = false;
144         missingParam = false;
145         QString unit = GetString(s);
146
147         if (unit.length() == 0)
148         {
149                 missingParam = true;
150                 return BUInch;
151         }
152
153         BasicUnit bu = BUInch;
154
155         if (unit == QString("inch") || unit == QString("in"))
156         {
157                 bu = BUInch;
158         }
159         else if (unit == QString("foot") || unit == QString("ft"))
160         {
161                 bu = BUFoot;
162         }
163         else if (unit == QString("yard") || unit == QString("yd"))
164         {
165                 bu = BUYard;
166         }
167         else
168         {
169                 Error(QString("bad unit '%1'").arg(unit));
170         }
171
172         return bu;
173 }
174
175 bool CommandProcessor::GetComma(QString & s)
176 {
177         ClearWhitespace(s);
178
179         if ((s.length() > 0) && (s[0] == QChar(',')))
180         {
181                 s.remove(0, 1);
182                 return true;
183         }
184
185         return false;
186 }
187
188 QString CommandProcessor::Process(QString cmd)
189 {
190         response.clear();
191         cmd = cmd.toLower();
192
193         if (Global::tool == TTParallel)
194         {
195                 response += QString("Parallel: %1").arg(cmd);
196                 bool goodDist = false, goodNum = false, goodBU = false;
197
198                 double d = GetDouble(cmd);
199                 int i = 0;
200                 int bu = 0;
201
202                 if (!missingParam && !parseError)
203                 {
204                         goodDist = true;
205                         bu = GetUnits(cmd);
206
207                         if (!missingParam && !parseError)
208                                 goodBU = true;
209                 }
210
211                 if (!parseError)
212                 {
213                         if (GetComma(cmd) == false)
214                         {
215                                 ClearWhitespace(cmd);
216
217                                 if (cmd.length() > 0)
218                                         Error("missing comma");
219                         }
220                         else
221                         {
222                                 i = GetInt(cmd);
223
224                                 if (!missingParam && !parseError)
225                                 {
226                                         goodNum = true;
227
228                                         ClearWhitespace(cmd);
229
230                                         if (cmd.length() > 0)
231                                                 Warning(QString("extra junk '%1' at end ignored").arg(cmd));
232                                 }
233                         }
234                 }
235
236                 if (!parseError)
237                 {
238                         if (goodBU)
239                                 Global::parallelBU = bu;
240
241                         if (goodDist)
242                                 Global::parallelDist = d * buInInches[Global::parallelBU];
243
244                         if (goodNum)
245                                 Global::parallelNum = i;
246
247                         emit(UpdateNeeded());
248                 }
249         }
250         else
251         {
252                 Error(QString("don't know how to '%1'").arg(cmd));
253         }
254
255         return response;
256 }