Code

Indent support for XSLT extensions output.
[inkscape.git] / src / dom / xpathtoken.h
1 #ifndef __XPATHTOKEN_H__
2 #define __XPATHTOKEN_H__
4 /**
5  * Phoebe DOM Implementation.
6  *
7  * This is a C++ approximation of the W3C DOM model, which follows
8  * fairly closely the specifications in the various .idl files, copies of
9  * which are provided for reference.  Most important is this one:
10  *
11  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
12  *
13  * Authors:
14  *   Bob Jamison
15  *
16  * Copyright (C) 2006 Bob Jamison
17  *
18  *  This library is free software; you can redistribute it and/or
19  *  modify it under the terms of the GNU Lesser General Public
20  *  License as published by the Free Software Foundation; either
21  *  version 2.1 of the License, or (at your option) any later version.
22  *
23  *  This library is distributed in the hope that it will be useful,
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26  *  Lesser General Public License for more details.
27  *
28  *  You should have received a copy of the GNU Lesser General Public
29  *  License along with this library; if not, write to the Free Software
30  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
31  */
34 #include "dom.h"
36 #include <math.h>
38 #include <cstdio>
39 #include <vector>
41 namespace org
42 {
43 namespace w3c
44 {
45 namespace dom
46 {
47 namespace xpath
48 {
50 typedef org::w3c::dom::DOMString DOMString;
53 class TokenExecutor;
56 //########################################################################
57 //# S T A C K    I T E M
58 //########################################################################
61 /**
62  * This represents a single value on the evaluation stack
63  */
64 class StackItem
65 {
66 public:
68     /**
69      *  Constructor
70      */
71     StackItem()
72         { init(); }
74     /**
75      *  Copy constructor
76      */
77     StackItem(const StackItem &other)
78         { assign(other); }
80     /**
81      *  Destructor
82      */
83     virtual ~StackItem()
84         {}
86     /**
87      *
88      */
89     StackItem &operator=(const StackItem &other)
90         { assign(other); return *this; }
92     //treat the stack item like an union of string, integer, and double
94     /**
95      * String value
96      */
97     DOMString sval;
99     /**
100      * Integer value
101      */
102     long      ival;
104     /**
105      * Double value;
106      */
107     double    dval;
110 private:
112     void init()
113         {
114         sval = "";
115         ival = 0;
116         dval = 0.0;
117         }
119     void assign(const StackItem &other)
120         {
121         sval = other.sval; 
122         ival = other.ival;
123         dval = other.dval;
124         }
126 };
130 //########################################################################
131 //# X P A T H    T O K E N
132 //########################################################################
134 class Token;
135 class Stack;
137 typedef bool (*TokenFunc)(Token &tok, Stack &stack);
140 /**
141  *  This is a pseudocode-type class that executes itself on a stack,
142  *  much like stack-oriented languages such as FORTH or Postscript.
143  *  Each token can pop zero or more tokens off the stack, and push
144  *  zero or one token back onto it.  When a list of tokens is completed,
145  *  a single stack value should be left on the stack.
146  */
147 class Token
149 public:
151     /**
152      * Token types.  Look in xpathtoken.cpp's function table
153      * to see how these types map to their respective
154      * functionalities
155      */
156     typedef enum
157         {
158         //primitives
159         TOK_NOP = 0,
160         TOK_STR,
161         TOK_INT,
162         TOK_FLOAT,
163         //operators
164         TOK_AND,
165         TOK_OR,
166         TOK_MOD,
167         TOK_DIV,
168         TOK_MUL,
169         TOK_DOUBLE_SLASH,
170         TOK_SLASH,
171         TOK_PIPE,
172         TOK_PLUS,
173         TOK_MINUS,
174         TOK_NEG,
175         TOK_EQUALS,
176         TOK_NOT_EQUALS,
177         TOK_LESS_THAN_EQUALS,
178         TOK_LESS_THAN,
179         TOK_GREATER_THAN_EQUALS,
180         TOK_GREATER_THAN,
181         //path types
182         TOK_ABSOLUTE,
183         TOK_RELATIVE,
184         TOK_STEP,
185         TOK_NAME_TEST,
186         TOK_EXPR,
187         TOK_UNION,
188         //axis types
189         TOK_AXIS_ANCESTOR_OR_SELF,
190         TOK_AXIS_ANCESTOR,
191         TOK_AXIS_ATTRIBUTE,
192         TOK_AXIS_CHILD,
193         TOK_AXIS_DESCENDANT_OR_SELF,
194         TOK_AXIS_DESCENDANT,
195         TOK_AXIS_FOLLOWING_SIBLING,
196         TOK_AXIS_FOLLOWING,
197         TOK_AXIS_NAMESPACE,
198         TOK_AXIS_PARENT,
199         TOK_AXIS_PRECEDING_SIBLING,
200         TOK_AXIS_PRECEDING,
201         TOK_AXIS_SELF,
202         //function types
203         TOK_FUNC_LAST,
204         TOK_FUNC_POSITION,
205         TOK_FUNC_COUNT,
206         TOK_FUNC_ID,
207         TOK_FUNC_LOCAL_NAME,
208         TOK_FUNC_NAMESPACE_URI,
209         TOK_FUNC_NAME,
210         TOK_FUNC_STRING,
211         TOK_FUNC_CONCAT,
212         TOK_FUNC_STARTS_WITH,
213         TOK_FUNC_CONTAINS,
214         TOK_FUNC_SUBSTRING_BEFORE,
215         TOK_FUNC_SUBSTRING_AFTER,
216         TOK_FUNC_SUBSTRING,
217         TOK_FUNC_STRING_LENGTH,
218         TOK_FUNC_NORMALIZE_SPACE,
219         TOK_FUNC_TRANSLATE,
220         TOK_FUNC_BOOLEAN,
221         TOK_FUNC_NOT,
222         TOK_FUNC_TRUE,
223         TOK_FUNC_FALSE,
224         TOK_FUNC_LANG,
225         TOK_FUNC_NUMBER,
226         TOK_FUNC_SUM,
227         TOK_FUNC_FLOOR,
228         TOK_FUNC_CEILING,
229         TOK_FUNC_ROUND,
230         } TokenType;
235     /**
236      *  Constructor with a NOP default type
237      */
238     Token()
239         { init(); }
241     /**
242      *  Constructor with a NOP default type
243      */
244     Token(int typeArg)
245         { init(); type = typeArg; }
247     /**
248      *  Constructor with a NOP default type
249      */
250     Token(int typeArg, 
251           long ivalArg, double dvalArg, const DOMString &svalArg)
252         { 
253         init();
254         type = typeArg,
255         ival = ivalArg;
256         dval = dvalArg;
257         sval = svalArg;
258         }
260     /**
261      * Copy constructor
262      */
263     Token(const Token &other)
264         { assign(other); }
266     /**
267      * Assignment
268      */
269     Token &operator=(const Token &other)
270         { assign(other); return *this; }
272     /**
273      * Destructor
274      */
275     virtual ~Token()
276         {}
278     /**
279      *  Return the enumerated TokenType of this token
280      */
281     virtual int getType()
282         { return type; }
284     /**
285      *  Return true if the type is one of the Axis types
286      *  above;
287      */
288     virtual bool isAxis()
289         {
290         return type>=TOK_AXIS_ANCESTOR_OR_SELF &&
291                  type <= TOK_AXIS_SELF;
292         }
293     /**
294      *  Return the string TokenType of this token
295      */
296     virtual DOMString getTypeString();
298     /**
299      *  Let this token execute itself on the given stack,
300      *  possibly adding Nodes to the node list.
301      */
302     virtual bool execute(Stack &stack)
303         {
304         if (tokenFunc)
305             return tokenFunc(*this, stack);
306         return false;
307         }
309     /**
310      *  Print the contents of this token
311      */
312     virtual void dump()
313         {
314         printf("%s %s %f %ld\n",
315             getTypeString().c_str(), sval.c_str(), dval, ival);
316         }
318     //treat the token like an union of string, integer, and double
320     /**
321      * String value
322      */
323     DOMString sval;
325     /**
326      * Integer value
327      */
328     long ival;
330     /**
331      * Double value;
332      */
333     double dval;
335     /**
336      *
337      */
338     static Token create(int type, long ival,
339               double dval, const DOMString &sval);
341     /**
342      *
343      */
344     static Token create(int type)
345         { return create(type, 0, 0.0, ""); }
347     /**
348      *
349      */
350     static Token create(int type, long val)
351         { return create(type, val, 0.0, ""); }
353     /**
354      *
355      */
356     static Token create(int type, double val)
357         { return create(type, 0, val, ""); }
359     /**
360      *
361      */
362     static Token create(int type, const DOMString &val)
363         { return create(type, 0, 0.0, val); }
367 protected:
369     /**
370      * The enmerated token type
371      */
372     int type;
374     /**
375      * The function that defines the behaviour of this token
376      */
377     TokenFunc tokenFunc;
380 private:
382     void init()
383         {
384         tokenFunc = NULL;
385         type      = TOK_NOP;
386         ival      = 0L;
387         dval      = 0.0;
388         //sval      = ""; //not necessary
389         }
391     void assign(const Token &other)
392         {
393         tokenFunc = other.tokenFunc;
394         type      = other.type;
395         sval      = other.sval;
396         ival      = other.ival;
397         dval      = other.dval;
398         }
401 };
404 //########################################################################
405 //# S T A C K
406 //########################################################################
408 /**
409  *
410  */
411 class Stack
413 public:
415     //# From 2.3, principal type of child axes
416     typedef enum
417         {
418         AXIS_ATTRIBUTE,
419         AXIS_NAMESPACE,
420         AXIS_ELEMENT
421         } PrincipalNodeType;
423     /**
424      *  Constructor
425      */
426     Stack(TokenExecutor &par) : parent(par)
427         { clear(); }
429     /**
430      *  Copy constructor
431      */
432     Stack(const Stack &other) : parent(other.parent)
433         { assign(other); }
435     /**
436      *  Destructor
437      */
438     virtual ~Stack()
439         {}
441     /**
442      *
443      */
444     Stack &operator=(const Stack &other)
445         { assign(other); return *this; }
447     /**
448      *
449      */
450     void push(StackItem &item)
451         { return stackItems.push_back(item); }
453     /**
454      *
455      */
456     StackItem pop()
457         {
458         if (stackItems.size() < 1)
459             {
460             //TODO: error here
461             StackItem item;
462             return item;
463             }
464         std::vector<StackItem>::iterator iter =
465                    stackItems.end() - 1;
466         StackItem item = *iter;
467         stackItems.erase(iter);
468         return item;
469         }
471     /**
472      *
473      */
474     virtual void clear()
475         {
476         stackItems.clear();
477         principalNodeType = AXIS_ELEMENT;
478         }
480 private:
482     void assign(const Stack &other)
483         {
484         principalNodeType = other.principalNodeType;
485         stackItems        = other.stackItems;
486         }
488     int principalNodeType;
490     std::vector<StackItem> stackItems;
492     TokenExecutor &parent;
494 };
499 //########################################################################
500 //# T O K E N    L I S T
501 //########################################################################
503 /**
504  *
505  */
506 class TokenList
508 public:
510     /**
511      *
512      */
513     TokenList()
514         { init(); }
516     /**
517      *
518      */
519     TokenList(const TokenList &other)
520         { assign(other); }
522     /**
523      *
524      */
525     TokenList &operator=(const TokenList &other)
526         { assign(other); return *this; }
528     /**
529      *
530      */
531     virtual ~TokenList()
532         { }
535     /**
536      *
537      */
538     virtual void add(const Token &token)
539         { tokens.push_back(token); }
541     /**
542      *
543      */
544     virtual std::vector<Token> &getTokens()
545         { return tokens; }
547     /**
548      *
549      */
550     virtual void dump()
551         {
552         for (unsigned int i=0 ; i<tokens.size() ; i++)
553             {
554             Token token = tokens[i];
555             token.dump();
556             }
557         }
559     /**
560      *
561      */
562     virtual void clear()
563        {
564        tokens.clear();
565        }
567 private:
570     void init()
571         {
572         clear();
573         }
575     void assign(const TokenList &other)
576         {
577         tokens = other.tokens;
578         }
580     std::vector<Token> tokens;
583 };
588 //########################################################################
589 //# T O K E N    E X E C U T O R
590 //########################################################################
593 /**
594  * A token evaluator, with stack and axis context
595  */
596 class TokenExecutor
598 public:
600     /**
601      * Constructor
602      */
603     TokenExecutor();
605     /**
606      * Copy constructor
607      */
608     TokenExecutor(const TokenExecutor &other);
610     /**
611      * Destructor
612      */
613     virtual ~TokenExecutor();
615     /**
616      *  Assign our values to those of the other
617      */
618     virtual void assign(const TokenExecutor &other);
620     /**
621      * Reset the stack to its original settings
622      */
623     virtual void reset();
625     /**
626      * Execute a list upon a given node.  For each Axis encountered,
627      * get the nodes encountered so far, and execute the rest of the
628      * list of tokens upon each of the nodes.
629      */
630     int execute(std::vector<Token> &tokens,
631                 int position,
632                 const NodePtr node,
633                 NodeList &nodeList);
635     /**
636      * Execute a token list on the stack
637      */
638     bool execute(TokenList &list,
639                  const NodePtr node,
640                  NodeList &result);
642 private:
644     /**
645      *
646      */
647     TokenList tokenList;
649     /**
650      *
651      */
652     NodeList nodeList;
655 };
660 } // namespace xpath
661 } // namespace dom
662 } // namespace w3c
663 } // namespace org
670 #endif  /* __XPATHTOKEN_H__ */
671 //########################################################################
672 //# E N D    O F    F I L E
673 //########################################################################