X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdom%2Fxpathtoken.cpp;h=ac0ead535c86b1e5ec6468e3811e018303ef30b7;hb=a8e0310afe0d9b31d25a143238dbbc0bc4a91860;hp=9d2b86215921014c9cb59db01c48d0e88927cd34;hpb=6232b46968ade11dd56fdb9627a2bda45d0dda7d;p=inkscape.git diff --git a/src/dom/xpathtoken.cpp b/src/dom/xpathtoken.cpp index 9d2b86215..ac0ead535 100644 --- a/src/dom/xpathtoken.cpp +++ b/src/dom/xpathtoken.cpp @@ -1,229 +1,1074 @@ -/** - * Phoebe DOM Implementation. - * - * This is a C++ approximation of the W3C DOM model, which follows - * fairly closely the specifications in the various .idl files, copies of - * which are provided for reference. Most important is this one: - * - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "xpathtoken.h" -#include - - - -namespace org -{ -namespace w3c -{ -namespace dom -{ -namespace xpath -{ - - -//######################################################################## -//# X P A T H S T A C K I T E M -//######################################################################## - -/** - * - */ -StackItem::StackItem() -{ - ival = 0L; - dval = 0.0; -} - - -/** - * - */ -StackItem::StackItem(const StackItem &other) -{ - sval = other.sval; - ival = other.ival; - dval = other.dval; -} - - -/** - * - */ -StackItem::~StackItem() -{ -} - - -//######################################################################## -//# X P A T H S T A C K -//######################################################################## - -/** - * - */ -Stack::Stack() -{ - size = 0; -} - - -/** - * - */ -Stack::Stack(const Stack &other) -{ - size = other.size; - for (int i=0 ; i=STACK_SIZE) - { - return; - } - items[size++] = item; -} - -/** - * - */ -StackItem Stack::pop() -{ - if (size<1) - { - StackItem item; - return item; - } - return items[--size]; -} - - - -//######################################################################## -//# T O K E N L I S T -//######################################################################## - -/** - * - */ -TokenList::TokenList() -{ -} - - -/** - * - */ -TokenList::~TokenList() -{ - clear(); -} - -/** - * - */ -void TokenList::clear() -{ - std::vector::iterator iter; - for (iter = tokens.begin() ; iter!= tokens.end() ; iter++) - { - delete (*iter); - } - tokens.clear(); -} - -/** - * - */ -void TokenList::add(Token *tok) -{ - tokens.push_back(tok); -} - -/** - * This method "executes" a list of Tokens in the context of a DOM root - * Node, returning a list of Nodes that match the xpath expression. - */ -NodeList TokenList::execute(const Node *root) -{ - NodeList list; - - if (!root) - return list; - - Stack stack; - //### Execute the token list - std::vector::iterator iter; - for (iter = tokens.begin() ; iter != tokens.end() ; iter++) - { - Token *tok = *iter; - tok->execute(stack, list); - } - - return list; -} - - -/** - * - */ -void TokenList::dump() -{ - std::vector::iterator iter; - printf("############# TOKENS\n"); - for (iter = tokens.begin() ; iter != tokens.end() ; iter++) - { - Token *tok = *iter; - tok->dump(); - } -} - - - - - -} // namespace xpath -} // namespace dom -} // namespace w3c -} // namespace org -//######################################################################## -//# E N D O F F I L E -//######################################################################## - - - +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2006 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "xpathtoken.h" +#include + + + +namespace org +{ +namespace w3c +{ +namespace dom +{ +namespace xpath +{ + + + +//######################################################################## +//# X P A T H T O K E N +//######################################################################## + +//######################################################################## +//# X P A T H T O K E N T Y P E S +//######################################################################## + + + +//########################### +//# V A L U E S +//########################### + +/** + * The following functions are called by a token's execute() + * method. These functions are what differentiate one token + * from another and give each its personality. +*/ + +static bool tokStr(Token &tok, Stack &stack) +{ + StackItem item; + item.sval = tok.sval; + stack.push(item); + return true; +} + +static bool tokFloat(Token &tok, Stack &stack) +{ + StackItem item; + item.dval = tok.dval; + stack.push(item); + return true; +} + +static bool tokInt(Token &tok, Stack &stack) +{ + StackItem item; + item.ival = tok.ival; + stack.push(item); + return true; +} + +static bool tokAnd(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = item1.ival && item2.ival; + stack.push(item1); + return true; +} + +static bool tokOr(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = item1.ival || item2.ival; + stack.push(item1); + return true; +} + +static bool tokMod(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.dval = fmod(item1.dval, item2.dval); + stack.push(item1); + return true; +} + + +static bool tokDiv(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.dval /= item2.dval; + stack.push(item1); + return true; +} + +static bool tokMul(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.dval *= item2.dval; + stack.push(item1); + return true; +} + +static bool tokPlus(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.dval += item2.dval; + stack.push(item1); + return true; +} + +static bool tokMinus(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.dval -= item2.dval; + stack.push(item1); + return true; +} + + +static bool tokNeg(Token &tok, Stack &stack) +{ + StackItem item = stack.pop(); + item.dval = -item.dval; + item.ival = -item.ival; + stack.push(item); + return true; +} + + +static bool tokEquals(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval == item2.dval); + stack.push(item1); + return true; +} + + +static bool tokNotEquals(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval != item2.dval); + stack.push(item1); + return true; +} + + +static bool tokLessThan(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval < item2.dval); + stack.push(item1); + return true; +} + + +static bool tokLessThanEquals(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval <= item2.dval); + stack.push(item1); + return true; +} + + +static bool tokGreaterThanEquals(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval >= item2.dval); + stack.push(item1); + return true; +} + + +static bool tokGreaterThan(Token &tok, Stack &stack) +{ + StackItem item1 = stack.pop(); + StackItem item2 = stack.pop(); + item1.ival = (item1.dval > item2.dval); + stack.push(item1); + return true; +} + + + + + + +//########################### +//# X P A T H I T E M S +//########################### + +static bool tokAbsolute(Token &tok, Stack &stack) +{ + return true; +} + +static bool tokRelative(Token &tok, Stack &stack) +{ + return true; +} + +static bool tokStep(Token &tok, Stack &stack) +{ + return true; +} + +static bool tokNameTest(Token &tok, Stack &stack) +{ + return true; +} + +static bool tokExpr(Token &tok, Stack &stack) +{ + return true; +} + +static bool tokUnion(Token &tok, Stack &stack) +{ + return true; +} + + + + +//########################### +//# A X I S +//########################### + + +static bool tokAxisAncestorOrSelf(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisAncestor(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisAttribute(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisChild(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisDescendantOrSelf(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisDescendant(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisFollowingSibling(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisFollowing(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisNamespace(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisParent(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisPrecedingSibling(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisPreceding(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokAxisSelf(Token &tok, Stack &stack) +{ + return true; +} + + + +//########################### +//# F U N C T I O N S +//########################### + + +static bool tokFuncLast(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncPosition(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncCount(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncId(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncLocalName(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncNamespaceUri(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncName(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncString(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncConcat(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncStartsWith(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncContains(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncSubstringBefore(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncSubstringAfter(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncSubstring(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncStringLength(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncNormalizeSpace(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncTranslate(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncBoolean(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncNot(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncTrue(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncFalse(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncLang(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncNumber(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncSum(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncFloor(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncCeiling(Token &tok, Stack &stack) +{ + return true; +} + + +static bool tokFuncRound(Token &tok, Stack &stack) +{ + return true; +} + + + +/** + * An entry for the token 'personality' table + */ +typedef struct +{ + int ival; + char *sval; + TokenFunc tokenFunc; +} TokenTableEntry; + + +/** + * The token personality table + */ +static TokenTableEntry tokenTable[] = +{ + //### primitives + { + Token::TOK_NOP, + "nop", + NULL + }, + { + Token::TOK_STR, + "str", + tokStr + }, + { + Token::TOK_INT, + "int", + tokInt + }, + { + Token::TOK_FLOAT, + "float", + tokFloat + }, + + //### operators + { + Token::TOK_AND, + "and", + tokAnd + }, + { + Token::TOK_OR, + "or", + tokOr + }, + { + Token::TOK_MOD, + "mod", + tokMod + }, + { + Token::TOK_DIV, + "div", + tokDiv + }, + { + Token::TOK_MUL, + "multiply", + tokMul + }, + { + Token::TOK_DOUBLE_SLASH, + "double-slash", + NULL + }, + { + Token::TOK_SLASH, + "slash", + NULL + }, + { + Token::TOK_PIPE, + "pipe", + NULL + }, + { + Token::TOK_PLUS, + "plus", + tokPlus + }, + { + Token::TOK_MINUS, + "minus", + tokMinus + }, + { + Token::TOK_NEG, + "neg", + tokNeg + }, + { + Token::TOK_EQUALS, + "equals", + tokEquals + }, + { + Token::TOK_NOT_EQUALS, + "not-equals", + tokNotEquals + }, + { + Token::TOK_LESS_THAN_EQUALS, + "less-than-equals", + tokLessThanEquals + }, + { + Token::TOK_LESS_THAN, + "less-than", + tokLessThan + }, + { + Token::TOK_GREATER_THAN_EQUALS, + "greater-than-equals", + tokGreaterThanEquals + }, + { + Token::TOK_GREATER_THAN, + "greater-than", + tokGreaterThan + }, + + //### path types + { + Token::TOK_ABSOLUTE, + "absolute", + tokAbsolute + }, + { + Token::TOK_RELATIVE, + "relative", + tokRelative + }, + { + Token::TOK_STEP, + "step", + tokStep + }, + { + Token::TOK_NAME_TEST, + "name-test", + tokNameTest + }, + { + Token::TOK_EXPR, + "expr", + tokExpr + }, + { + Token::TOK_UNION, + "union", + tokUnion + }, + + //### axis types + { + Token::TOK_AXIS_ANCESTOR_OR_SELF, + "axis-ancestor-or-self", + tokAxisAncestorOrSelf + }, + { + Token::TOK_AXIS_ANCESTOR, + "axis-ancestor", + tokAxisAncestor + }, + { + Token::TOK_AXIS_ATTRIBUTE, + "axis-attribute", + tokAxisAttribute + }, + { + Token::TOK_AXIS_CHILD, + "axis-child", + tokAxisChild + }, + { + Token::TOK_AXIS_DESCENDANT_OR_SELF, + "axis-descendant-or-self", + tokAxisDescendantOrSelf + }, + { + Token::TOK_AXIS_DESCENDANT, + "axis-descendant", + tokAxisDescendant + }, + { + Token::TOK_AXIS_FOLLOWING_SIBLING, + "axis-following-sibling", + tokAxisFollowingSibling + }, + { + Token::TOK_AXIS_FOLLOWING, + "axis-following", + tokAxisFollowing + }, + { + Token::TOK_AXIS_NAMESPACE, + "axis-namespace", + tokAxisNamespace + }, + { + Token::TOK_AXIS_PARENT, + "axis-parent", + tokAxisParent + }, + { + Token::TOK_AXIS_PRECEDING_SIBLING, + "axis-preceding-sibling", + tokAxisPrecedingSibling + }, + { + Token::TOK_AXIS_PRECEDING, + "axis-preceding", + tokAxisPreceding + }, + { + Token::TOK_AXIS_SELF, + "axis-self", + tokAxisSelf + }, + + //### function types + { + Token::TOK_FUNC_LAST, + "func-last", + tokFuncLast + }, + { + Token::TOK_FUNC_POSITION, + "func-position", + tokFuncPosition + }, + { + Token::TOK_FUNC_COUNT, + "func-count", + tokFuncCount + }, + { + Token::TOK_FUNC_ID, + "func-id", + tokFuncId + }, + { + Token::TOK_FUNC_LOCAL_NAME, + "func-local-name", + tokFuncLocalName + }, + { + Token::TOK_FUNC_NAMESPACE_URI, + "func-namespace-uri", + tokFuncNamespaceUri + }, + { + Token::TOK_FUNC_NAME, + "func-name", + tokFuncName + }, + { + Token::TOK_FUNC_STRING, + "func-string", + tokFuncString + }, + { + Token::TOK_FUNC_CONCAT, + "func-concat", + tokFuncConcat + }, + { + Token::TOK_FUNC_STARTS_WITH, + "func-starts-with", + tokFuncStartsWith + }, + { + Token::TOK_FUNC_CONTAINS, + "func-contains", + tokFuncContains + }, + { + Token::TOK_FUNC_SUBSTRING_BEFORE, + "func-substring-before", + tokFuncSubstringBefore + }, + { + Token::TOK_FUNC_SUBSTRING_AFTER, + "func-substring-after", + tokFuncSubstringAfter + }, + { + Token::TOK_FUNC_SUBSTRING, + "func-substring", + tokFuncSubstring + }, + { + Token::TOK_FUNC_STRING_LENGTH, + "func-string-length", + tokFuncStringLength + }, + { + Token::TOK_FUNC_NORMALIZE_SPACE, + "func-normalize-space", + tokFuncNormalizeSpace + }, + { + Token::TOK_FUNC_TRANSLATE, + "func-translate", + tokFuncTranslate + }, + { + Token::TOK_FUNC_BOOLEAN, + "func-boolean", + tokFuncBoolean + }, + { + Token::TOK_FUNC_NOT, + "func-not", + tokFuncNot + }, + { + Token::TOK_FUNC_TRUE, + "func-true", + tokFuncTrue + }, + { + Token::TOK_FUNC_FALSE, + "func-false", + tokFuncFalse + }, + { + Token::TOK_FUNC_LANG, + "func-lang", + tokFuncLang + }, + { + Token::TOK_FUNC_NUMBER, + "func-number", + tokFuncNumber + }, + { + Token::TOK_FUNC_SUM, + "func-sum", + tokFuncSum + }, + { + Token::TOK_FUNC_FLOOR, + "func-floor", + tokFuncFloor + }, + { + Token::TOK_FUNC_CEILING, + "func-ceiling", + tokFuncCeiling + }, + { + Token::TOK_FUNC_ROUND, + "func-round", + tokFuncRound + }, + + { -1, + (char *)0, + NULL + } +}; + + +/** + * Return the string TokenType of this token + * (in the .cpp file) + */ +DOMString Token::getTypeString() +{ + DOMString ret = "unknown"; + for (TokenTableEntry *entry = tokenTable ; entry->sval ; entry++) + { + if (entry->ival == type) + { + ret = entry->sval; + break; + } + } + return ret; +} + + +/** + * Create a token of the given type, giving it + * the data and personalities it needs + */ +Token Token::create(int type, long ival, + double dval, const DOMString &sval) +{ + Token tok(type, ival, dval, sval); + for (TokenTableEntry *entry = tokenTable ; entry->sval ; entry++) + { + if (entry->ival == type) + { + tok.tokenFunc = entry->tokenFunc; + break; + } + } + + return tok; +} + + + + + + + + +//######################################################################## +//# X P A T H E X E C U T O R +//######################################################################## + +/** + * + */ +TokenExecutor::TokenExecutor() +{ + reset(); +} + + +/** + * + */ +TokenExecutor::TokenExecutor(const TokenExecutor &other) +{ + reset(); + assign(other); +} + + +/** + * + */ +TokenExecutor::~TokenExecutor() +{ +} + + +/** + * + */ +void TokenExecutor::assign(const TokenExecutor &other) +{ + tokenList = other.tokenList; +} + + +/** + * + */ +void TokenExecutor::reset() +{ +} + + + + +/** + * Execute a list upon a given node. For each Axis encountered, + * get the nodes encountered so far, and execute the rest of the + * list of tokens upon each of the nodes. + */ +int TokenExecutor::execute(std::vector &tokens, + int position, + const NodePtr node, + NodeList &result) +{ + Stack stack(*this); + + NodeList contextNodes; + + int length = (int) tokens.size(); + + for ( ; position < length ; position ++) + { + Token tok = tokens[position]; + if (tok.isAxis()) + { + int pos2 = 0; + //Do rest of tokens with the nodes we have found so far + for (unsigned int i = 0 ; i &tokens = tokenList.getTokens(); + if (execute(tokens, 0, node, nodeList) < 0) + { + //error message + return false; + } + + result = nodeList; + + return true; +} + + + + + + + + + + + + + +} // namespace xpath +} // namespace dom +} // namespace w3c +} // namespace org +//######################################################################## +//# E N D O F F I L E +//######################################################################## + + +