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