ATFInterpreter.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "ATFInterpreter.h"
21
22#include <tqvaluestack.h>
23#include <tqfile.h>
24
25const char ATFInterpreter::PNT_BG[] = "POINT {";
26const char ATFInterpreter::X_BG[] = "X {";
27const char ATFInterpreter::Y_BG[] = "Y {";
28const char ATFInterpreter::ATTR_BG[] = "ATTRIB {";
29const char ATFInterpreter::END[] = "}";
30
31// fields
32const int ATFInterpreter::ST_WIDTH = 1;
33const int ATFInterpreter::ST_HEIGHT = 2;
34const int ATFInterpreter::ST_VARIABLE = 3;
35const int ATFInterpreter::ST_NUMBER = 4;
36const int ATFInterpreter::ST_OPERATOR = 5;
37
38// operators
39const char ATFInterpreter::OP_EQUAL = '=';
40const char ATFInterpreter::OP_PLUS = '+';
41const char ATFInterpreter::OP_MINUS = '-';
42const char ATFInterpreter::OP_MULT = '*';
43const char ATFInterpreter::OP_DIV = '/';
44const char ATFInterpreter::COMMENT = '#';
45
46// allowed variables
47const char ATFInterpreter::VAR_1 = 'a';
48const char ATFInterpreter::VAR_2 = 'b';
49const char ATFInterpreter::VAR_3 = 'c';
50const char ATFInterpreter::VAR_4 = 'd';
51const char ATFInterpreter::VAR_5 = 'e';
52const char ATFInterpreter::VAR_6 = 'f';
53const char ATFInterpreter::VAR_X = 'x';
54const char ATFInterpreter::VAR_Y = 'y';
55const char ATFInterpreter::VAR_VARIA = 'v';
56const char ATFInterpreter::VAR_PW = 'p';
57const char ATFInterpreter::VAR_W = 'w';
58const char ATFInterpreter::VAR_H = 'h';
59
60// level (depth) of the syntax
61const int ATFInterpreter::LEVEL_NULL = 0;
62const int ATFInterpreter::LEVEL_POINT = 1;
63const int ATFInterpreter::LEVEL_X = 2;
64const int ATFInterpreter::LEVEL_Y = 3;
65const int ATFInterpreter::LEVEL_ATTR = 4;
66
67// numbers
68const char ATFInterpreter::NUM_0 = '0';
69const char ATFInterpreter::NUM_1 = '1';
70const char ATFInterpreter::NUM_2 = '2';
71const char ATFInterpreter::NUM_3 = '3';
72const char ATFInterpreter::NUM_4 = '4';
73const char ATFInterpreter::NUM_5 = '5';
74const char ATFInterpreter::NUM_6 = '6';
75const char ATFInterpreter::NUM_7 = '7';
76const char ATFInterpreter::NUM_8 = '8';
77const char ATFInterpreter::NUM_9 = '9';
78
79/******************************************************************/
80/* class ATFInterpreter */
81/******************************************************************/
82
83/*====================== constructor =============================*/
84ATFInterpreter::ATFInterpreter() {
85}
86
87/*======================= destrcutor =============================*/
88ATFInterpreter::~ATFInterpreter()
89{
90 coordList.setAutoDelete(true);
91 attrLs.setAutoDelete( true );
92}
93
94void ATFInterpreter::load(const TQString & fileName)
95{
96 TQString line;
97 TQFile ptA(fileName);
98
99 coordList.clear();
100 lines.clear();
101
102 if (ptA.open(IO_ReadOnly))
103 {
104 while (!ptA.atEnd())
105 {
106 ptA.readLine(line,255);
107 lines.append(line.simplifyWhiteSpace());
108 }
109 ptA.close();
110 interpret();
111 }
112}
113
114TQPointArray ATFInterpreter::getPointArray(int wid,int heig)
115{
116 unsigned int px = 0,py = 0,a = 0,b = 0,c = 0,d = 0,e = 0,f = 0;
117 unsigned int tmp = 0,num = 0;
118 bool calc = false,res = false;
119 char op = OP_EQUAL,var = VAR_1;
120 TQPtrList<Sign> slp;
121 TQPointArray pntArray(coordList.count());
122
123 if (!coordList.isEmpty())
124 {
125 for (coordPtr=coordList.first();coordPtr != 0;coordPtr=coordList.next())
126 {
127 for (unsigned int i = 1; i<= 14; i++)
128 {
129 switch (i)
130 {
131 case 1: slp = coordPtr->pntX.var1; break;
132 case 2: slp = coordPtr->pntX.var2; break;
133 case 3: slp = coordPtr->pntX.var3; break;
134 case 4: slp = coordPtr->pntX.var4; break;
135 case 5: slp = coordPtr->pntX.var5; break;
136 case 6: slp = coordPtr->pntX.var6; break;
137 case 7: slp = coordPtr->pntX.result; break;
138 case 8: slp = coordPtr->pntY.var1; break;
139 case 9: slp = coordPtr->pntY.var2; break;
140 case 10: slp = coordPtr->pntY.var3; break;
141 case 11: slp = coordPtr->pntY.var4; break;
142 case 12: slp = coordPtr->pntY.var5; break;
143 case 13: slp = coordPtr->pntY.var6; break;
144 case 14: slp = coordPtr->pntY.result; break;
145 }
146 if (!slp.isEmpty())
147 {
148 tmp = 0;
149 for (signPtr=slp.first();signPtr != 0;signPtr=slp.next())
150 {
151 switch (signPtr->type)
152 {
153 case ST_WIDTH: { num = wid; calc = true; res = false;} break;
154 case ST_HEIGHT: { num = heig; calc = true; res = false;} break;
155 case ST_OPERATOR: { op = signPtr->op; calc = false; res = false;} break;
156 case ST_VARIABLE: { var = signPtr->var; calc = false; res = true;} break;
157 case ST_NUMBER: { num = signPtr->num; calc = true; res = false;} break;
158 }
159 if (calc)
160 {
161 switch (op)
162 {
163 case OP_EQUAL: tmp = num; break;
164 case OP_PLUS: tmp += num; break;
165 case OP_MINUS: tmp -= num; break;
166 case OP_MULT: tmp *= num; break;
167 case OP_DIV: tmp /= num; break;
168 }
169 }
170 else if (res)
171 {
172 switch (var)
173 {
174 case VAR_1: num = a; break;
175 case VAR_2: num = b; break;
176 case VAR_3: num = c; break;
177 case VAR_4: num = d; break;
178 case VAR_5: num = e; break;
179 case VAR_6: num = f; break;
180 }
181 switch (op)
182 {
183 case OP_EQUAL: tmp = num; break;
184 case OP_PLUS: tmp += num; break;
185 case OP_MINUS: tmp -= num; break;
186 case OP_MULT: tmp *= num; break;
187 case OP_DIV: tmp /= num; break;
188 }
189 }
190 }
191 if (i == 1 || i == 8) a = tmp;
192 if (i == 2 || i == 9) b = tmp;
193 if (i == 3 || i == 10) c = tmp;
194 if (i == 4 || i == 11) d = tmp;
195 if (i == 5 || i == 12) e = tmp;
196 if (i == 6 || i == 13) f = tmp;
197 if (i == 7) px = tmp;
198 if (i == 14) py = tmp;
199 }
200 }
201 pntArray.setPoint(coordList.at(),px,py);
202 }
203 }
204 return pntArray;
205}
206
207TQPtrList<ATFInterpreter::AttribList> ATFInterpreter::getAttribList()
208{
209 if(!attrLs.isEmpty())
210 return attrLs;
211
212 AttribList *attribPtr;
213
214 if (!coordList.isEmpty())
215 {
216 for (coordPtr=coordList.first();coordPtr != 0;coordPtr=coordList.next())
217 {
218 attribPtr = new AttribList;
219 attribPtr->isVariable = coordPtr->isVariable;
220 attribPtr->pwDiv = coordPtr->pwDiv;
221 attrLs.append(attribPtr);
222 }
223 }
224 attrLs.setAutoDelete(true);
225 return attrLs;
226}
227
228void ATFInterpreter::interpret()
229{
230 TQValueStack<int> level;
231 Value value;
232 bool v = false;
233 int pw = 1;
234 CoordStruct coord;
235 AttribStruct attrib;
236
237 level.push(LEVEL_NULL);
238
239 for (TQStringList::Iterator it=lines.begin(); it!=lines.end(); ++it)
240 {
241 if (!(*it).isEmpty() && (*it).at(0) != COMMENT)
242 {
243 if (level.top() == LEVEL_NULL)
244 {
245 if ((*it) == PNT_BG)
246 {
247 coordPtr = new Coord;
248 level.push(LEVEL_POINT);
249 }
250 }
251 else if (level.top() == LEVEL_POINT)
252 {
253 if ((*it) == X_BG)
254 level.push(LEVEL_X);
255 else if ((*it) == Y_BG)
256 level.push(LEVEL_Y);
257 else if ((*it) == ATTR_BG)
258 level.push(LEVEL_ATTR);
259 else if ((*it) == TQString(END))
260 {
261 level.pop();
262 coordList.append(coordPtr);
263 }
264 }
265 else if (level.top() == LEVEL_X || level.top() == LEVEL_Y || level.top() == LEVEL_ATTR)
266 {
267 switch (((*it).at(0)).latin1())
268 {
269 case VAR_1:
270 {
271 coord.a = (*it);
272 value.var1 = getVar(*it);
273 } break;
274 case VAR_2:
275 {
276 coord.b = (*it);
277 value.var2 = getVar(*it);
278 } break;
279 case VAR_3:
280 {
281 coord.c = (*it);
282 value.var3 = getVar(*it);
283 } break;
284 case VAR_4:
285 {
286 coord.d = (*it);
287 value.var4 = getVar(*it);
288 } break;
289 case VAR_5:
290 {
291 coord.e = (*it);
292 value.var5 = getVar(*it);
293 } break;
294 case VAR_6:
295 {
296 coord.f = (*it);
297 value.var6 = getVar(*it);
298 } break;
299 case VAR_X: case VAR_Y:
300 {
301 coord.result = (*it);
302 value.result = getVar(*it);
303 } break;
304 case VAR_VARIA:
305 {
306 if ((*it).find('0') != -1) v = false;
307 else v = true;
308 attrib.isVariable = (*it);
309 } break;
310 case VAR_PW:
311 {
312 pw = 1; pw = ((*it).at(4)).latin1() - 48;
313 attrib.pwDiv = (*it);
314 } break;
315 case '}':
316 {
317 switch (level.top())
318 {
319 case LEVEL_X:
320 {
321 coordPtr->pntX = value;
322 coord.a = TQString();
323 coord.b = TQString();
324 coord.c = TQString();
325 coord.d = TQString();
326 coord.e = TQString();
327 coord.f = TQString();
328 coord.result = TQString();
329 } break;
330 case LEVEL_Y:
331 {
332 coordPtr->pntY = value;
333 coord.a = TQString();
334 coord.b = TQString();
335 coord.c = TQString();
336 coord.d = TQString();
337 coord.e = TQString();
338 coord.f = TQString();
339 coord.result = TQString();
340 } break;
341 case LEVEL_ATTR:
342 {
343 coordPtr->isVariable = v;
344 coordPtr->pwDiv = pw;
345 pw = 1;
346 v = false;
347 attrib.isVariable = TQString();
348 attrib.pwDiv = 1;
349 } break;
350 }
351 level.pop();
352 } break;
353 }
354 }
355 }
356 }
357}
358
359TQPtrList<ATFInterpreter::Sign> ATFInterpreter::getVar(const TQString &s)
360{
361 TQPtrList<Sign> list;
362
363 for (unsigned int i=1; i<s.length(); ++i)
364 {
365 if(s.at(i)==' ')
366 continue;
367 signPtr = new Sign;
368 switch (s.at(i).latin1())
369 {
370 case VAR_W: signPtr->type = ST_WIDTH; break;
371 case VAR_H: signPtr->type = ST_HEIGHT; break;
372 case VAR_1:
373 {
374 signPtr->type = ST_VARIABLE;
375 signPtr->var = VAR_1;
376 } break;
377 case VAR_2:
378 {
379 signPtr->type = ST_VARIABLE;
380 signPtr->var = VAR_2;
381 } break;
382 case VAR_3:
383 {
384 signPtr->type = ST_VARIABLE;
385 signPtr->var = VAR_3;
386 } break;
387 case VAR_4:
388 {
389 signPtr->type = ST_VARIABLE;
390 signPtr->var = VAR_4;
391 } break;
392 case VAR_5:
393 {
394 signPtr->type = ST_VARIABLE;
395 signPtr->var = VAR_5;
396 } break;
397 case VAR_6:
398 {
399 signPtr->type = ST_VARIABLE;
400 signPtr->var = VAR_6;
401 } break;
402 case OP_EQUAL:
403 {
404 signPtr->type = ST_OPERATOR;
405 signPtr->op = OP_EQUAL;
406 } break;
407 case OP_PLUS:
408 {
409 signPtr->type = ST_OPERATOR;
410 signPtr->op = OP_PLUS;
411 } break;
412 case OP_MINUS:
413 {
414 signPtr->type = ST_OPERATOR;
415 signPtr->op = OP_MINUS;
416 } break;
417 case OP_DIV:
418 {
419 signPtr->type = ST_OPERATOR;
420 signPtr->op = OP_DIV;
421 } break;
422 case OP_MULT:
423 {
424 signPtr->type = ST_OPERATOR;
425 signPtr->op = OP_MULT;
426 } break;
427 case NUM_0: case NUM_1: case NUM_2: case NUM_3: case NUM_4:
428 case NUM_5: case NUM_6: case NUM_7: case NUM_8: case NUM_9:
429 {
430 signPtr->type = ST_NUMBER;
431 if (s.length() - 1 > i)
432 {
433 switch (s.at(i+1).latin1())
434 {
435 case NUM_0: case NUM_1: case NUM_2: case NUM_3: case NUM_4:
436 case NUM_5: case NUM_6: case NUM_7: case NUM_8: case NUM_9:
437 {
438 signPtr->num = (s.at(i).latin1() - 48) * 10 + s.at(i+1).latin1() - 48;
439 i++;
440 } break;
441 default:
442 signPtr->num = s.at(i).latin1() - 48; break;
443 }
444 }
445 else
446 signPtr->num = s.at(i).latin1() - 48;
447 } break;
448 }
449 list.append(signPtr);
450 }
451 return list;
452}