1 /* -*- mode: c++ -*-
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * The Original Code is the Sablotron XSLT Processor.
13  *
14  * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15  * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16  * Ginger Alliance Ltd. All Rights Reserved.
17  *
18  * Contributor(s):
19  *
20  * Alternatively, the contents of this file may be used under the
21  * terms of the GNU General Public License Version 2 or later (the
22  * "GPL"), in which case the provisions of the GPL are applicable
23  * instead of those above.  If you wish to allow use of your
24  * version of this file only under the terms of the GPL and not to
25  * allow others to use your version of this file under the MPL,
26  * indicate your decision by deleting the provisions above and
27  * replace them with the notice and other provisions required by
28  * the GPL.  If you do not delete the provisions above, a recipient
29  * may use your version of this file under either the MPL or the
30  * GPL.
31  */
32 
33 #ifndef VertsHIncl
34 #define VertsHIncl
35 
36 // GP: clean
37 
38 #include "base.h"
39 #include "arena.h"
40 #include "datastr.h"
41 #include "expr.h"
42 #include "hash.h"
43 // #include "tree.h"
44 
45 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48 
49 #ifdef SABLOT_DEBUGGER
50 #include "debugger.h"
51 #endif
52 
53 class Tree;
54 
55 class Context;
56 class Expression;
57 class OutputterObj;
58 class OutputDefinition;
59 class AttList;
60 
61 typedef void *NodeHandle;
62 class SubtreeInfo;
63 
64 /****************************************
65 V e r t e x
66 ****************************************/
67 
68 class Vertex : public SabArenaMember
69 {
70 public:
71     Vertex(Tree& owner_, VTYPE avt = VT_VERTEX_WF)
owner(owner_)72       : owner(owner_), vt(avt), parent(NULL), ordinal(0), subtree(NULL),
73 	outputDocument(NULL)
74     {
75         stamp = lineno = 0;
76 	    instanceData = NULL;
77     };
78     virtual ~Vertex();
79     virtual eFlag execute(Sit S, Context *, Bool resolvingGlobals);
80     virtual eFlag value(Sit S, DStr &, Context *);
81     virtual eFlag startCopy(Sit S, OutputterObj& out);
82     virtual eFlag endCopy(Sit S, OutputterObj& out);
83     virtual eFlag copy(Sit S, OutputterObj& out);
84     virtual void speak(DStr &, SpeakMode);
85     void setParent(Vertex *v);
86     Vertex* getPreviousSibling();
87     Vertex* getNextSibling();
88     virtual const QName& getName() const;
89     Tree& getOwner() const;
90     virtual eFlag serialize(Sit S, OutputterObj &out);
91     virtual eFlag getMatchingList(Sit S, Expression& match, Context& result);
92 
93     Tree &owner;
94     VTYPE vt;
95     Vertex *parent;
96     int ordinal;
97     SubtreeInfo* subtree;
98     int lineno;
99     int stamp;          // the vertex number in doc order (0 = root)
100     void report(Sit S, MsgType type, MsgCode code, const Str& arg1, const Str& arg2) const;
101     HashTable& dict() const;
setInstanceData(void * data)102     void setInstanceData(void *data) {instanceData = data;}
getInstanceData()103     void* getInstanceData() {return instanceData;}
104     virtual void makeStamps(int& stamp);
105 
106     // set the subtree information (base URI etc.)
setSubtreeInfo(SubtreeInfo * subtree_)107     void setSubtreeInfo(SubtreeInfo* subtree_)
108 	{ subtree = subtree_; }
109     // get the subtree information
getSubtreeInfo()110     SubtreeInfo* getSubtreeInfo() const
111 	{ return subtree; }
112     int getImportPrecedence();
setOutputDocument(OutputDocument * doc)113     void setOutputDocument(OutputDocument *doc)
114       {outputDocument = doc;}
getOutputDefinition()115     OutputDocument* getOutputDefinition() {return outputDocument;};
116 protected:
117     eFlag startDocument(Sit S, OutputterObj*& out);
118     eFlag finishDocument(Sit S);
119 private:
120     void *instanceData;    // for Perl interface
121     // this is set in Tree::appendVertex
122     OutputDocument *outputDocument;
123 };
124 
125 /****************************************
126 V e r t e x L i s t
127 ****************************************/
128 
129 // FIXME: changed PList to SList...
130 
131 class VertexList: public SList<Vertex*>
132 {
133 public:
134     VertexList(int logBlockSize_ = LIST_SIZE_SMALL);
135     virtual ~VertexList();
136     eFlag execute (Sit S, Context*, Bool resolvingGlobals);
137     eFlag value(Sit S, DStr&, Context *);
138     virtual void speak(DStr &, SpeakMode);
139     virtual void append(Vertex *);
140     void rm(int ndx);
141     void destructMembers();
142     int strip();
143     eFlag copy(Sit S, OutputterObj& out);
144     void insertBefore(Vertex *newChild, int refIndex);
145     int getIndex(Vertex *v);
146     eFlag serialize(Sit S, OutputterObj &out);
147     void makeStamps(int& stamp);
148     eFlag getMatchingList(Sit S, Expression& match, Context& result);
149 };
150 
151 /****************************************
152 A r e n a V e r t e x L i s t
153 ****************************************/
154 
155 class SabArenaVertexList : public VertexList, public SabArenaMember
156 {
157 public:
158     SabArenaVertexList(SabArena *arena__=NULL, int logBlockSize_ = LIST_SIZE_SMALL)
VertexList(logBlockSize_)159         : VertexList(logBlockSize_), arena_(arena__)
160     {
161     };
162 
~SabArenaVertexList()163     ~SabArenaVertexList()
164     {
165         deppendall();
166     }
167 
168 protected:
claimMemory(int nbytes)169     virtual Vertex** claimMemory( int nbytes ) const
170     {
171         return arena_ ? (Vertex**)(arena_ -> armalloc(nbytes)) :
172             (Vertex**)VertexList::claimMemory(nbytes);
173     }
174 
reclaimMemory(Vertex ** p,int newbytes,int oldbytes)175     virtual Vertex** reclaimMemory( Vertex**p, int newbytes, int oldbytes ) const
176     {
177         if (!arena_)
178             return VertexList::reclaimMemory(p, newbytes, oldbytes);
179         else if (newbytes > oldbytes)
180         {
181             Vertex **newpos = (Vertex**) (arena_ -> armalloc(newbytes));
182             memcpy(newpos, p, oldbytes);
183             return newpos;
184         }
185         else
186             return p;
187     }
188 
returnMemory(Vertex ** & p)189     virtual void returnMemory( Vertex**&p ) const
190     {
191         if (arena_)
192             arena_ -> arfree(p);
193         else
194             if (p) VertexList::returnMemory(p);
195         p = NULL;
196     }
197     SabArena *arena_;
198 };
199 
200 
201 /****************************************
202 D a d d y
203 ****************************************/
204 
205 class Daddy : public Vertex
206 {
207 public:
208     Daddy(Tree& owner_, VTYPE avt = VT_DADDY_WF);
209     virtual ~Daddy(void);
210     virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
211    	virtual eFlag value(Sit S, DStr &, Context *);
212     virtual eFlag newChild(Sit S, Vertex*);
213     virtual eFlag checkChildren(Sit S);
214     virtual void speak(DStr &, SpeakMode);
215     virtual int strip();
216     virtual eFlag getMatchingList(Sit S, Expression& match, Context& result);
217     //
218     SabArenaVertexList contents;
219 };
220 
221 /****************************************
222 A t t r i b u t e
223 ****************************************/
224 
225 class Attribute : public Vertex
226 {
227 public:
228     Attribute(Tree& owner_, const QName&, const Str&, XSL_ATT);
229     virtual ~Attribute();
230     eFlag buildExpr(Sit S, Bool, ExType);
231     virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
232     virtual void speak(DStr &, SpeakMode);
233     virtual eFlag value(Sit S, DStr &, Context *);
234     virtual eFlag startCopy(Sit S, OutputterObj& out);
235     virtual const QName& getName() const;
236     void setValue(const Str& newValue);
237     virtual eFlag serialize(Sit S, OutputterObj &out);
238     QName name;
239     SabArenaStr cont;
240     Expression *expr;
241     XSL_ATT op;
242 };
243 
244 /****************************************
245 A t t L i s t
246 ****************************************/
247 
248 class AttList: public SabArenaVertexList
249 {
250 public:
AttList(SabArena * arena_)251     AttList(SabArena *arena_)
252         : SabArenaVertexList(arena_)
253     {};
254     Attribute* find(XSL_ATT);
255     // assumes that attName belongs to the same hash
256     Attribute* find(const QName& attName);
257     int findNdx(const QName& attName);
258 };
259 
260 /*****************************************************************
261     N m S p a c e
262 *****************************************************************/
263 typedef enum
264 {
265     NSKIND_PARENT = 0,   // namespace is NOT explicitly declared by owning element - for instance inherited via namespace scoping
266     NSKIND_DECLARED = 1  // namespace is explicitly declared by owning element
267 } NsKind;
268 
269 class NmSpace: public Vertex
270 {
271 public:
272   //  NmSpace(Tree& owner_, Phrase _prefix, Phrase _uri, NsKind _kind);
273     NmSpace(Tree& owner_, Phrase _prefix, Phrase _uri,
274 	    Bool _excluded = FALSE, NsKind _kind = NSKIND_PARENT);
275     virtual ~NmSpace();
276     Phrase
277         prefix,
278         uri;
279     QName name;
280     NsKind kind;
281     Bool excluded;
282     unsigned int usageCount;
283     virtual eFlag execute(Sit S, Context *, Bool resolvingGlobals);
284     virtual eFlag executeSkip(Sit S, Context *, Bool resolvingGlobals,
285 			      EQName & exName, Bool aliased);
286     virtual void speak(DStr &, SpeakMode);
287    	virtual eFlag value(Sit S, DStr &, Context *);
288     virtual eFlag startCopy(Sit S, OutputterObj& out);
289     virtual const QName& getName() const;
290     virtual eFlag serialize(Sit S, OutputterObj &out);
291     NsKind setKind(NsKind kind_);
292 };
293 
294 /*****************************************************************
295     N S L i s t
296 *****************************************************************/
297 
298 class NSList : public SabArenaVertexList
299 {
300 public:
301   NSList (SabArena* arena_ = NULL)
302     : SabArenaVertexList(arena_,0)
303   { }
304 
305   ~NSList();
306   NmSpace* find(Phrase) const;
307   int findNdx(Phrase prefix) const;
308   eFlag resolve(Sit S, Phrase&, Bool) const;
309   void unresolve(Phrase&) const;
310   void giveCurrent(Sit S, NSList &, Tree*, int nscount) const;
311   void swallow(Sit S, NSList &other, Tree *strTree, Tree *t);
312   eFlag executeSkip(Sit S, Context *, Bool resolvingGlobals,
313 		    EQName & exName, Bool aliased);
314   // unresolve the qname's prefix
315   void findPrefix(QName &q);
316   void report(Sit S, MsgType type, MsgCode code,
317 	      const Str &arg1, const Str &arg2) const;
318   void setPrefixKind(Phrase prefix_, NsKind kind_) const;
319   void incPrefixUsage(Phrase prefix_) const;
320   void decPrefixUsage(Phrase prefix_) const;
321 };
322 
323 
324 /****************************************
325 E l e m e n t
326 ****************************************/
327 
328 class Element : public Daddy
329 {
330 public:
331     Element(Tree& owner_, QName&, VTYPE = VT_ELEMENT_WF);
332     virtual ~Element();
333     virtual int strip();
334     virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
335     virtual eFlag executeFallback(Sit S, Context *c, Bool &hasSome,
336 				  Bool resolvingGlobals);
337     virtual eFlag newChild(Sit S, Vertex*);
338     virtual void speak(DStr &, SpeakMode);
339     void removeBindings(Sit S);
340     virtual eFlag startCopy(Sit S, OutputterObj& out);
341     virtual eFlag endCopy(Sit S, OutputterObj& out);
342     virtual eFlag copy(Sit S, OutputterObj& out);
343     virtual const QName& getName() const;
344     virtual eFlag serialize(Sit S, OutputterObj &out);
345     virtual eFlag serializeSubtree(Sit S, OutputterObj &out);
346     void removeChild(Vertex *child);
347     virtual void makeStamps(int& stamp);
348     virtual eFlag getMatchingList(Sit S, Expression& match, Context& result);
349 
350     // set qname to "prefix:local". Last param says
351     // whether to expand the default namespace
352     eFlag setLogical(Sit S, QName &q, const Str&,
353 		     Bool defaultToo, Phrase defUri = UNDEF_PHRASE) const;
354     //
355     NSList
356         namespaces;
357     AttList
358         atts;
359     QName
360         name;
361     QNameList* attSetNames(Bool);
362     eFlag executeAttributeSets(Sit S, Context *c, Bool resolvingGlobals);
363     Bool preserveSpace;
364 #ifdef SABLOT_DEBUGGER
365     Breakpoint *breakpoint;
366 #endif
367 protected:
368     QNameList *attsNames;
369 private:
370 };
371 
372 /****************************************
373 R o o t N o d e
374 ****************************************/
375 
376 class RootNode : public Element
377 {
378 public:
RootNode(Tree & owner_,QName & name_)379     RootNode(Tree& owner_, QName& name_)
380         : Element(owner_, name_, VT_ROOT_WF)
381     {
382     };
383     virtual ~RootNode();
384     virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
385     virtual eFlag newChild(Sit S, Vertex*);
386     virtual eFlag checkChildren(Sit S);
387     virtual void speak(DStr &, SpeakMode);
388     virtual eFlag startCopy(Sit S, OutputterObj& out);
389     virtual eFlag endCopy(Sit S, OutputterObj& out);
390     virtual eFlag copy(Sit S, OutputterObj& out);
391     virtual eFlag serialize(Sit S, OutputterObj &out);
392 };
393 
394 /****************************************
395 T e x t
396 ****************************************/
397 
398 class Text : public Vertex
399 {
400 public:
401     SabArenaStr cont;
402     Text(Tree& owner_, char *acont, int alen=0);
403     virtual ~Text();
404     virtual eFlag execute(Sit S, Context *, Bool resolvingGlobals);
405     virtual void speak(DStr &, SpeakMode);
406    	virtual eFlag value(Sit S, DStr &, Context *);
407     virtual eFlag startCopy(Sit S, OutputterObj& out);
408     virtual eFlag serialize(Sit S, OutputterObj &out);
409     void beCDATA();
410     Bool isCDATA();
411 private:
412     Bool isCDATAFlag;
413 };
414 
415 
416 /****************************************
417 C o m m e n t
418 ****************************************/
419 
420 class Comment: public Vertex
421 {
422 public:
423     Comment(Tree& owner_, const Str& cont_);
424     virtual ~Comment();
425     virtual eFlag execute(Sit S, Context *, Bool resolvingGlobals);
426     virtual void speak(DStr &, SpeakMode);
427    	virtual eFlag value(Sit S, DStr &, Context *);
428     virtual eFlag startCopy(Sit S, OutputterObj& out);
429     virtual eFlag serialize(Sit S, OutputterObj &out);
430     SabArenaStr cont;
431 };
432 
433 
434 /****************************************
435 P r o c I n s t r
436 ****************************************/
437 
438 class ProcInstr: public Vertex
439 {
440 public:
441     ProcInstr(Tree& owner_, Phrase name_, const Str& cont_);
442     virtual ~ProcInstr();
443     virtual eFlag execute(Sit S, Context *, Bool resolvingGlobals);
444     virtual void speak(DStr &, SpeakMode);
445    	virtual eFlag value(Sit S, DStr &, Context *);
446     virtual eFlag startCopy(Sit S, OutputterObj& out);
447     virtual const QName& getName() const;
448     virtual eFlag serialize(Sit S, OutputterObj &out);
449     SabArenaStr cont;
450     QName name;
451 };
452 
453 
454 /****************************************
455 X S L E l e m e n t
456 ****************************************/
457 
458 class XSLElement : public Element
459 {
460 public:
461     XSLElement(Tree& owner_, QName&, XSL_OP);
462     virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
463     virtual eFlag newChild(Sit S, Vertex*);
464     eFlag checkToplevel(Sit S);
465     virtual eFlag checkChildren(Sit S);
466     void checkExtraChildren(int& k);
467     Expression* getAttExpr(XSL_ATT);
468     virtual int strip();
469     XSL_OP op;
470     eFlag checkAtts(Sit S);
471 //    VertexList defs;
472 private:
473     // applies only to XSL_APPLY_TEMPLATES and XSL_FOR_EACH:
474     eFlag makeSortDefs(Sit S, SortDefList &sortDefs, Context *c);
475     // applies only to XSL_SORT:
476     eFlag make1SortDef(Sit S, SortDef *&def, Context *c);
477 };
478 
479 /****************************************
480 X S L E l e m e n t
481 ****************************************/
482 enum ExtNamespace {
483   EXTNS_EXSLT_FUNCTIONS,
484   EXTNS_EXSLT_FUNCTIONS_2,
485   EXTNS_EXSLT_COMMON,
486   EXTNS_UNKNOWN
487 };
488 
489 enum ExtElement {
490   //exslt.org/functions
491   EXTE_EXSLT_FUNCTIONS = 0,
492   EXTE_EXSLT_SCRIPT = 0,
493   //exsl.org/common
494   EXTE_EXSLT_COMMON = 100,
495   EXTE_EXSLT_DOCUMENT = 100,
496   EXTE_UNKNOWN
497 };
498 
499 class ExtensionElement : public Element
500 {
501 public:
502   ExtensionElement(Tree& owner_, QName& aqname);
503   virtual eFlag execute(Sit S, Context *c, Bool resolvingGlobals);
504   virtual eFlag checkChildren(Sit S);
505   eFlag checkAtts(Sit S);
506   static Bool elementAvailable(Tree &t, QName &name);
507 private:
508   static void lookupExt(Tree &t, QName &name,
509 			ExtNamespace &extns_, ExtElement &op_);
510 #ifdef ENABLE_JS
511   eFlag executeEXSLTScript(Sit S, Context *c, Bool resolvingGlobals);
512 #endif
513   eFlag executeEXSLTDocument(Sit S, Context *c, Bool resolvingGlobals);
514   eFlag checkHasAttr(Sit S, const char *name);
515   eFlag exsltDocGetOutputterDef(Sit S, Context *c, OutputDefinition &def);
516   ExtNamespace extns;
517   ExtElement op;
518 };
519 
520 #endif //ifndef VertsHIncl
521 
522