+ // The following are inlined here for speed\r
+ /** Tag(x): returns the tag identifier of node x. */\r
+\r
+ TagType Tag(treeNode x) {\r
+ if (tags_blen == 8)\r
+ return (TagType) (((uchar*)tags_fix)[(int) x]);\r
+ else\r
+ return (TagType) get_field(tags_fix,tags_blen, (int) x);\r
+ }\r
+\r
+ /** FirstChild(x): returns the first child of node x, or NULLT if the node is a leaf\r
+ */\r
+ treeNode FirstChild(treeNode x) {\r
+ NULLT_IF(x==NULLT);\r
+ return fast_first_child(Par, x);\r
+ };\r
+\r
+\r
+ /** FirstElement(x): returns the first non text, non attribute child of node x, or NULLT\r
+ * if none.\r
+ */\r
+ treeNode FirstElement(treeNode x){\r
+ {\r
+ NULLT_IF(x==NULLT);\r
+ x = fast_first_child(Par, x);\r
+ NULLT_IF(x == NULLT);\r
+ switch (Tag(x)){\r
+ \r
+ case PCDATA_TAG_ID:\r
+ x = x+2;\r
+ return (fast_inspect(Par,x)==OP)? x : NULLT;\r
+ \r
+ case ATTRIBUTE_TAG_ID: \r
+ x = fast_next_sibling(Par,x);\r
+ if (x != NULLT && Tag(x) == PCDATA_TAG_ID){\r
+ x = x+2;\r
+ return (fast_inspect(Par,x)==OP)? x : NULLT;\r
+ } \r
+ else return x; \r
+ default:\r
+ return x;\r
+ }\r
+ }\r
+ };\r
+\r
+ /** NextSibling(x): returns the next sibling of node x, or NULLT if none \r
+ * exists. */\r
+ \r
+ treeNode NextSibling(treeNode x) {\r
+ NULLT_IF (x <= 0);\r
+ return fast_next_sibling(Par, x);\r
+ };\r
+ \r
+ /** NextElement(x): returns the first non text, non attribute sibling of node x, or NULLT\r
+ * if none.\r
+ */\r
+ treeNode NextElement(treeNode x)\r
+ {\r
+ NULLT_IF(x <= 0);\r
+ x = fast_next_sibling(Par, x);\r
+ NULLT_IF(x == NULLT); \r
+ if (Tag(x) == PCDATA_TAG_ID){\r
+ x = x+2;\r
+ return (fast_inspect(Par,x)==OP)? x : NULLT;\r
+ }\r
+ else return x; \r
+ };\r
+ /** TaggedDesc(x,tag): returns the first node tagged tag with larger \r
+ * preorder than x and within the subtree of x. Returns NULT if there \r
+ * is none. */\r
+ treeNode TaggedDescendant(treeNode x, TagType tag)\r
+ {\r
+ \r
+ int s = (int) Tags->select_next(tag,node2tagpos(x));\r
+ NULLT_IF (s == -1);\r
+ \r
+ treeNode y = tagpos2node(s); // transforms the tag position into a node position\r
+ \r
+ return (fast_is_ancestor(Par,x,y) ? y : NULLT);\r
+ };\r
+ \r
+ treeNode TaggedFollowingBelow(treeNode x, TagType tag,treeNode ancestor)\r
+ {\r
+ treeNode close = fast_find_close(Par, x);\r
+ treeNode s = tagpos2node(Tags->select_next(tag, close));\r
+ \r
+ if (ancestor == Root() || s == NULLT || s < fast_find_close(Par,ancestor)) return s;\r
+ else return NULLT;\r
+ };\r
+ \r