Code

Move contextual info to Stack
[inkscape.git] / src / dom / xpathtoken.h
1 #ifndef __XPATHTOKEN_H__\r
2 #define __XPATHTOKEN_H__\r
3 \r
4 /**\r
5  * Phoebe DOM Implementation.\r
6  *\r
7  * This is a C++ approximation of the W3C DOM model, which follows\r
8  * fairly closely the specifications in the various .idl files, copies of\r
9  * which are provided for reference.  Most important is this one:\r
10  *\r
11  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html\r
12  *\r
13  * Authors:\r
14  *   Bob Jamison\r
15  *\r
16  * Copyright (C) 2006 Bob Jamison\r
17  *\r
18  *  This library is free software; you can redistribute it and/or\r
19  *  modify it under the terms of the GNU Lesser General Public\r
20  *  License as published by the Free Software Foundation; either\r
21  *  version 2.1 of the License, or (at your option) any later version.\r
22  *\r
23  *  This library is distributed in the hope that it will be useful,\r
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
26  *  Lesser General Public License for more details.\r
27  *\r
28  *  You should have received a copy of the GNU Lesser General Public\r
29  *  License along with this library; if not, write to the Free Software\r
30  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
31  */\r
32 \r
33 \r
34 #include "dom.h"\r
35 \r
36 #include <math.h>\r
37 \r
38 #include <vector>\r
39 \r
40 namespace org\r
41 {\r
42 namespace w3c\r
43 {\r
44 namespace dom\r
45 {\r
46 namespace xpath\r
47 {\r
48 \r
49 typedef org::w3c::dom::DOMString DOMString;\r
50 \r
51 /**\r
52  * This represents a single value on the evaluation stack\r
53  */\r
54 class StackItem\r
55 {\r
56 public:\r
57 \r
58     /**\r
59      *  Constructor\r
60      */\r
61     StackItem();\r
62 \r
63     /**\r
64      *  Copy constructor\r
65      */\r
66     StackItem(const StackItem &other);\r
67 \r
68     /**\r
69      *  Destructor\r
70      */\r
71     virtual ~StackItem();\r
72 \r
73     //treat the stack item like an union of string, integer, and double\r
74 \r
75     /**\r
76      * String value\r
77      */\r
78     DOMString sval;\r
79 \r
80     /**\r
81      * Integer value\r
82      */\r
83     long      ival;\r
84 \r
85     /**\r
86      * Double value;\r
87      */\r
88     double    dval;\r
89 \r
90 };\r
91 \r
92 #define STACK_SIZE 1024\r
93 \r
94 /**\r
95  * An evaluation stack\r
96  */\r
97 class Stack\r
98 {\r
99 public:\r
100 \r
101     /**\r
102      * Constructor\r
103      */\r
104     Stack();\r
105 \r
106     /**\r
107      * Copy constructor\r
108      */\r
109     Stack(const Stack &other);\r
110 \r
111     /**\r
112      * Destructor\r
113      */\r
114     virtual ~Stack();\r
115 \r
116     /**\r
117      *  Assign our values to those of the other\r
118      */\r
119     virtual void assign(const Stack &other);\r
120 \r
121     /**\r
122      * Reset the stack to its original settings\r
123      */\r
124     virtual void reset();\r
125 \r
126     /**\r
127      * Push a stack item onto the stack\r
128      */\r
129     virtual void push(StackItem &item);\r
130 \r
131     /**\r
132      * Pop a stack item from the stack\r
133      */\r
134     virtual StackItem pop();\r
135 \r
136     /**\r
137      * Set the root node\r
138      */\r
139     virtual void setRootNode(const Node *node);\r
140 \r
141     /**\r
142      * Get the current node list;\r
143      */\r
144     virtual NodeList &getNodeList();\r
145 \r
146 \r
147 private:\r
148 \r
149     Node *root;\r
150     NodeList nodeList;\r
151 \r
152     StackItem items[STACK_SIZE];\r
153     int size;\r
154 };\r
155 \r
156 \r
157 \r
158 \r
159 /**\r
160  *  This is a pseudocode-type class that executes itself on a stack,\r
161  *  much like stack-oriented languages such as FORTH or Postscript.\r
162  *  Each token can pop zero or more tokens off the stack, and push\r
163  *  zero or one token back onto it.  When a list of tokens is completed,\r
164  *  a single stack value should be left on the stack.\r
165  */\r
166 class Token\r
167 {\r
168 public:\r
169 \r
170     /**\r
171      * Token types.  Look in xpathtoken.cpp's function table\r
172      * to see how these types map to their respective\r
173      * functionalities\r
174      */\r
175     typedef enum\r
176         {\r
177         TOK_NOP = 0,\r
178         TOK_STR,\r
179         TOK_INT,\r
180         TOK_FLOAT,\r
181         //operators\r
182         TOK_AND,\r
183         TOK_OR,\r
184         TOK_MOD,\r
185         TOK_DIV,\r
186         TOK_MULTIPLY,\r
187         TOK_DOUBLE_SLASH,\r
188         TOK_SLASH,\r
189         TOK_PIPE,\r
190         TOK_PLUS,\r
191         TOK_MINUS,\r
192         TOK_NEG,\r
193         TOK_EQUALS,\r
194         TOK_NOT_EQUALS,\r
195         TOK_LESS_THAN_EQUALS,\r
196         TOK_LESS_THAN,\r
197         TOK_GREATER_THAN_EQUALS,\r
198         TOK_GREATER_THAN,\r
199         //path types\r
200         TOK_ABSOLUTE,\r
201         TOK_RELATIVE,\r
202         TOK_STEP,\r
203         TOK_EXPR,\r
204         TOK_UNION,\r
205         //function types\r
206         TOK_POSITION\r
207         } TokenType;\r
208     /**\r
209      *  Constructor with a NOP default type\r
210      */\r
211     Token()\r
212         {\r
213         type     = TOK_NOP;\r
214         stype    = "nop";\r
215         ival     = 0L;\r
216         dval     = 0.0;\r
217         }\r
218 \r
219     /**\r
220      * Copy constructor\r
221      */\r
222     Token(const Token &other)\r
223         {\r
224         type     = other.type;\r
225         stype    = other.stype;\r
226         sval     = other.sval;\r
227         ival     = other.ival;\r
228         dval     = other.dval;\r
229         }\r
230 \r
231     /**\r
232      * Destructor\r
233      */\r
234     virtual ~Token()\r
235         {}\r
236 \r
237     /**\r
238      *  Return the enumerated TokenType of this token\r
239      */\r
240     virtual int getType()\r
241         { return type; }\r
242 \r
243     /**\r
244      *  Let this token execute itself on the given stack,\r
245      *  possibly adding Nodes to the node list.\r
246      */\r
247     virtual bool execute(Stack &stack)\r
248         { return true; }\r
249 \r
250     /**\r
251      *  Print the contents of this token\r
252      */\r
253     virtual void dump()\r
254         {\r
255         printf("%s %s %f %ld\n", stype, sval.c_str(), dval, ival);\r
256         }\r
257 \r
258     //treat the token like an union of string, integer, and double\r
259 \r
260     /**\r
261      * String value\r
262      */\r
263     DOMString sval;\r
264 \r
265     /**\r
266      * Integer value\r
267      */\r
268     long      ival;\r
269 \r
270     /**\r
271      * Double value;\r
272      */\r
273     double    dval;\r
274 \r
275 protected:\r
276 \r
277     /**\r
278      * The enmerated token type\r
279      */\r
280     int type;\r
281 \r
282     /**\r
283      * String type\r
284      */\r
285     char *stype;\r
286 \r
287 private:\r
288 \r
289 \r
290 };\r
291 \r
292 \r
293 //########################################################################\r
294 //# X P A T H    T O K E N\r
295 //########################################################################\r
296 \r
297 \r
298 \r
299 //###########################\r
300 //# V A L U E S\r
301 //###########################\r
302 \r
303 class TokStr : public Token\r
304 {\r
305 public:\r
306     TokStr(const DOMString &val)\r
307         {\r
308         type = TOK_STR;\r
309         stype = "str";\r
310         sval = val;\r
311         }\r
312     virtual bool execute(Stack &stack)\r
313         {\r
314         StackItem item;\r
315         item.sval = sval;\r
316         stack.push(item);\r
317         return true;\r
318         }\r
319 };\r
320 \r
321 class TokFloat : public Token\r
322 {\r
323 public:\r
324     TokFloat(double val)\r
325         {\r
326         type = TOK_FLOAT;\r
327         stype = "float";\r
328         dval = val;\r
329         }\r
330     virtual bool execute(Stack &stack)\r
331         {\r
332         StackItem item;\r
333         item.dval = dval;\r
334         stack.push(item);\r
335         return true;\r
336         }\r
337 };\r
338 \r
339 class TokInt : public Token\r
340 {\r
341 public:\r
342     TokInt(long val)\r
343         {\r
344         type = TOK_INT;\r
345         stype = "int";\r
346         ival = val;\r
347         }\r
348     virtual bool execute(Stack &stack)\r
349         {\r
350         StackItem item;\r
351         item.ival = ival;\r
352         stack.push(item);\r
353         return true;\r
354         }\r
355 };\r
356 \r
357 class TokAnd : public Token\r
358 {\r
359 public:\r
360     TokAnd()\r
361         {\r
362         type = TOK_AND;\r
363         stype = "and";\r
364         }\r
365     virtual bool execute(Stack &stack)\r
366         {\r
367         StackItem item1 = stack.pop();\r
368         StackItem item2 = stack.pop();\r
369         item1.ival = item1.ival && item2.ival;\r
370         stack.push(item1);\r
371         return true;\r
372         }\r
373 };\r
374 \r
375 class TokOr : public Token\r
376 {\r
377 public:\r
378     TokOr()\r
379         {\r
380         type = TOK_OR;\r
381         stype = "or";\r
382         }\r
383     virtual bool execute(Stack &stack)\r
384         {\r
385         StackItem item1 = stack.pop();\r
386         StackItem item2 = stack.pop();\r
387         item1.ival = item1.ival || item2.ival;\r
388         stack.push(item1);\r
389         return true;\r
390         }\r
391 };\r
392 \r
393 class TokMod : public Token\r
394 {\r
395 public:\r
396     TokMod()\r
397         {\r
398         type = TOK_MOD;\r
399         stype = "mod";\r
400         }\r
401     virtual bool execute(Stack &stack)\r
402         {\r
403         StackItem item1 = stack.pop();\r
404         StackItem item2 = stack.pop();\r
405         item1.dval = fmod(item1.dval, item2.dval);\r
406         stack.push(item1);\r
407         return true;\r
408         }\r
409 };\r
410 \r
411 class TokDiv : public Token\r
412 {\r
413 public:\r
414     TokDiv()\r
415         {\r
416         type = TOK_DIV;\r
417         stype = "div";\r
418         }\r
419     virtual bool execute(Stack &stack)\r
420         {\r
421         StackItem item1 = stack.pop();\r
422         StackItem item2 = stack.pop();\r
423         item1.dval /= item2.dval;\r
424         stack.push(item1);\r
425         return true;\r
426         }\r
427 };\r
428 \r
429 class TokMul : public Token\r
430 {\r
431 public:\r
432     TokMul()\r
433         {\r
434         type = TOK_MULTIPLY;\r
435         stype = "mul";\r
436         }\r
437     virtual bool execute(Stack &stack)\r
438         {\r
439         StackItem item1 = stack.pop();\r
440         StackItem item2 = stack.pop();\r
441         item1.dval *= item2.dval;\r
442         stack.push(item1);\r
443         return true;\r
444         }\r
445 };\r
446 \r
447 class TokPlus : public Token\r
448 {\r
449 public:\r
450     TokPlus()\r
451         {\r
452         type = TOK_PLUS;\r
453         stype = "plus";\r
454         }\r
455     virtual bool execute(Stack &stack)\r
456         {\r
457         StackItem item1 = stack.pop();\r
458         StackItem item2 = stack.pop();\r
459         item1.dval += item2.dval;\r
460         stack.push(item1);\r
461         return true;\r
462         }\r
463 };\r
464 \r
465 class TokMinus : public Token\r
466 {\r
467 public:\r
468     TokMinus()\r
469         {\r
470         type = TOK_MINUS;\r
471         stype = "minus";\r
472         }\r
473     virtual bool execute(Stack &stack)\r
474         {\r
475         StackItem item1 = stack.pop();\r
476         StackItem item2 = stack.pop();\r
477         item1.dval -= item2.dval;\r
478         stack.push(item1);\r
479         return true;\r
480         }\r
481 };\r
482 \r
483 class TokNeg : public Token\r
484 {\r
485 public:\r
486     TokNeg()\r
487         {\r
488         type = TOK_NEG;\r
489         stype = "neg";\r
490         }\r
491     virtual bool execute(Stack &stack)\r
492         {\r
493         StackItem item;\r
494         item.dval = -dval;\r
495         item.ival = -ival;\r
496         stack.push(item);\r
497         return true;\r
498         }\r
499 };\r
500 \r
501 class TokEquals : public Token\r
502 {\r
503 public:\r
504     TokEquals()\r
505         {\r
506         type = TOK_EQUALS;\r
507         stype = "equals";\r
508         }\r
509     virtual bool execute(Stack &stack)\r
510         {\r
511         StackItem item1 = stack.pop();\r
512         StackItem item2 = stack.pop();\r
513         item1.ival = (item1.dval == item2.dval);\r
514         stack.push(item1);\r
515         return true;\r
516         }\r
517 };\r
518 \r
519 class TokNotEquals : public Token\r
520 {\r
521 public:\r
522     TokNotEquals()\r
523         {\r
524         type = TOK_NOT_EQUALS;\r
525         stype = "neq";\r
526         }\r
527     virtual bool execute(Stack &stack)\r
528         {\r
529         StackItem item1 = stack.pop();\r
530         StackItem item2 = stack.pop();\r
531         item1.ival = (item1.dval != item2.dval);\r
532         stack.push(item1);\r
533         return true;\r
534         }\r
535 };\r
536 \r
537 class TokLessThanEquals : public Token\r
538 {\r
539 public:\r
540     TokLessThanEquals()\r
541         {\r
542         type = TOK_LESS_THAN_EQUALS;\r
543         stype = "lt_eq";\r
544         }\r
545     virtual bool execute(Stack &stack)\r
546         {\r
547         StackItem item1 = stack.pop();\r
548         StackItem item2 = stack.pop();\r
549         item1.ival = (item1.dval <= item2.dval);\r
550         stack.push(item1);\r
551         return true;\r
552         }\r
553 };\r
554 \r
555 class TokLessThan : public Token\r
556 {\r
557 public:\r
558     TokLessThan()\r
559         {\r
560         type = TOK_LESS_THAN;\r
561         stype = "lt";\r
562         }\r
563     virtual bool execute(Stack &stack)\r
564         {\r
565         StackItem item1 = stack.pop();\r
566         StackItem item2 = stack.pop();\r
567         item1.ival = (item1.dval < item2.dval);\r
568         stack.push(item1);\r
569         return true;\r
570         }\r
571 };\r
572 \r
573 class TokGreaterThanEquals : public Token\r
574 {\r
575 public:\r
576     TokGreaterThanEquals()\r
577         {\r
578         type = TOK_GREATER_THAN_EQUALS;\r
579         stype = "gt";\r
580         }\r
581     virtual bool execute(Stack &stack)\r
582         {\r
583         StackItem item1 = stack.pop();\r
584         StackItem item2 = stack.pop();\r
585         item1.ival = (item1.dval >= item2.dval);\r
586         stack.push(item1);\r
587         return true;\r
588         }\r
589 };\r
590 \r
591 class TokGreaterThan : public Token\r
592 {\r
593 public:\r
594     TokGreaterThan()\r
595         {\r
596         type = TOK_GREATER_THAN;\r
597         stype = "gt_eq";\r
598         }\r
599     virtual bool execute(Stack &stack)\r
600         {\r
601         StackItem item1 = stack.pop();\r
602         StackItem item2 = stack.pop();\r
603         item1.ival = (item1.dval > item2.dval);\r
604         stack.push(item1);\r
605         return true;\r
606         }\r
607 };\r
608 \r
609 \r
610 //###########################\r
611 //# X P A T H    I T E M S\r
612 //###########################\r
613 \r
614 class TokAbsolute : public Token\r
615 {\r
616 public:\r
617     TokAbsolute()\r
618         {\r
619         type = TOK_ABSOLUTE;\r
620         stype = "absolute";\r
621         }\r
622     virtual bool execute(Stack &stack)\r
623         {\r
624         return true;\r
625         }\r
626 };\r
627 \r
628 class TokRelative : public Token\r
629 {\r
630 public:\r
631     TokRelative()\r
632         {\r
633         type = TOK_RELATIVE;\r
634         stype = "relative";\r
635         }\r
636     virtual bool execute(Stack &stack)\r
637         {\r
638         return true;\r
639         }\r
640 };\r
641 \r
642 class TokStep : public Token\r
643 {\r
644 public:\r
645     TokStep()\r
646         {\r
647         type = TOK_STEP;\r
648         stype = "step";\r
649         }\r
650     virtual bool execute(Stack &stack)\r
651         {\r
652         return true;\r
653         }\r
654 };\r
655 \r
656 class TokExpr : public Token\r
657 {\r
658 public:\r
659     TokExpr()\r
660         {\r
661         type = TOK_EXPR;\r
662         stype = "token";\r
663         }\r
664     virtual bool execute(Stack &stack)\r
665         {\r
666         return true;\r
667         }\r
668 };\r
669 \r
670 class TokUnion : public Token\r
671 {\r
672 public:\r
673     TokUnion()\r
674         {\r
675         type = TOK_UNION;\r
676         stype = "union";\r
677         }\r
678     virtual bool execute(Stack &stack)\r
679         {\r
680         return true;\r
681         }\r
682 };\r
683 \r
684 \r
685 \r
686 //###########################\r
687 //# F U N C T I O N S\r
688 //###########################\r
689 \r
690 class TokPosition : public Token\r
691 {\r
692 public:\r
693     TokPosition()\r
694         {\r
695         type = TOK_POSITION;\r
696         stype = "position";\r
697         }\r
698     virtual bool execute(Stack &stack)\r
699         {\r
700         return true;\r
701         }\r
702 };\r
703 \r
704 \r
705 \r
706 //########################################################################\r
707 //# T O K E N    L I S T\r
708 //########################################################################\r
709 \r
710 /**\r
711  *\r
712  */\r
713 class TokenList\r
714 {\r
715 public:\r
716 \r
717     /**\r
718      *\r
719      */\r
720     TokenList();\r
721 \r
722     /**\r
723      *\r
724      */\r
725     virtual ~TokenList();\r
726 \r
727     /**\r
728      *\r
729      */\r
730     virtual void clear();\r
731 \r
732     /**\r
733      *\r
734      */\r
735     virtual void add(Token *tok);\r
736 \r
737     /**\r
738      *  This method "executes" a list of Tokens in the context of a DOM root\r
739      *  Node, returning a list of Nodes that match the xpath expression.\r
740      */\r
741     NodeList execute(const Node *root);\r
742 \r
743     /**\r
744      *\r
745      */\r
746     virtual void dump();\r
747 \r
748 private:\r
749 \r
750 \r
751     std::vector<Token *> tokens;\r
752 \r
753 };\r
754 \r
755 \r
756 \r
757 } // namespace xpath\r
758 } // namespace dom\r
759 } // namespace w3c\r
760 } // namespace org\r
761 \r
762 \r
763 \r
764 \r
765 \r
766 \r
767 #endif  /* __XPATHTOKEN_H__ */\r
768 //########################################################################\r
769 //# E N D    O F    F I L E\r
770 //########################################################################\r
771 \r