~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/dom/xpathparser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 * Authors:
11
11
 *   Bob Jamison
12
12
 *
13
 
 * Copyright (C) 2006 Bob Jamison
 
13
 * Copyright (C) 2006-2007 Bob Jamison
14
14
 *
15
15
 *  This library is free software; you can redistribute it and/or
16
16
 *  modify it under the terms of the GNU Lesser General Public
618
618
//# X P A T H    G R A M M A R    P A R S I N G
619
619
//#########################################################################
620
620
 
621
 
 
622
 
void XPathParser::tokAdd(Token *tok)
 
621
//## Various shorthand methods to add a token to the list
 
622
void XPathParser::tokAdd(const Token &tok)
623
623
{
624
624
    tokens.add(tok);
625
625
}
626
626
 
 
627
void XPathParser::tokAdd(int type)
 
628
{
 
629
    tokens.add(Token::create(type));
 
630
}
 
631
 
 
632
void XPathParser::tokAdd(int type, long val)
 
633
{
 
634
    tokens.add(Token::create(type, val));
 
635
}
 
636
 
 
637
void XPathParser::tokAdd(int type, double val)
 
638
{
 
639
    tokens.add(Token::create(type, val));
 
640
}
 
641
 
 
642
void XPathParser::tokAdd(int type, const DOMString &val)
 
643
{
 
644
    tokens.add(Token::create(type, val));
 
645
}
 
646
 
 
647
 
 
648
 
 
649
 
 
650
 
 
651
//########################################
 
652
//# Grammar - specific parsing
 
653
//########################################
 
654
 
627
655
/**
628
656
 * [1]  LocationPath ::=
629
657
 *        RelativeLocationPath
639
667
    int p2 = getAbsoluteLocationPath(p, depth+1);
640
668
    if (p2 > p)
641
669
        {
642
 
        tokens.add(new TokAbsolute());
 
670
        tokAdd(Token::TOK_ABSOLUTE);
643
671
        return p2;
644
672
        }
645
673
 
646
674
    p2 = getRelativeLocationPath(p, depth+1);
647
675
    if (p2 > p)
648
676
        {
649
 
        tokens.add(new TokRelative());
 
677
        tokAdd(Token::TOK_RELATIVE);
650
678
        return p2;
651
679
        }
652
680
 
731
759
            {
732
760
            p++;
733
761
            // a '//' is an abbreviation for /descendant-or-self:node()/
734
 
            tokAdd(new TokAxisDescendantOrSelf());
 
762
            tokAdd(Token::TOK_AXIS_DESCENDANT_OR_SELF);
735
763
            p2 = getRelativeLocationPath(p, depth+1);
736
764
            if (p2 < 0)
737
765
                {
831
859
        switch (axisType)
832
860
            {
833
861
            case ANCESTOR_OR_SELF:
834
 
                tokAdd(new TokAxisAncestorOrSelf());
 
862
                tokAdd(Token::TOK_AXIS_ANCESTOR_OR_SELF);
 
863
                break;
835
864
            case ANCESTOR:
836
 
                tokAdd(new TokAxisAncestor());
 
865
                tokAdd(Token::TOK_AXIS_ANCESTOR);
 
866
                break;
837
867
            case ATTRIBUTE:
838
 
                tokAdd(new TokAxisAttribute());
 
868
                tokAdd(Token::TOK_AXIS_ATTRIBUTE);
 
869
                break;
839
870
            case CHILD:
840
 
                tokAdd(new TokAxisChild());
 
871
                tokAdd(Token::TOK_AXIS_CHILD);
 
872
                break;
841
873
            case DESCENDANT_OR_SELF:
842
 
                tokAdd(new TokAxisDescendantOrSelf());
 
874
                tokAdd(Token::TOK_AXIS_DESCENDANT_OR_SELF);
 
875
                break;
843
876
            case DESCENDANT:
844
 
                tokAdd(new TokAxisDescendant());
 
877
                tokAdd(Token::TOK_AXIS_DESCENDANT);
 
878
                break;
845
879
            case FOLLOWING_SIBLING:
846
 
                tokAdd(new TokAxisFollowingSibling());
 
880
                tokAdd(Token::TOK_AXIS_FOLLOWING_SIBLING);
 
881
                break;
847
882
            case FOLLOWING:
848
 
                tokAdd(new TokAxisFollowing());
 
883
                tokAdd(Token::TOK_AXIS_FOLLOWING);
 
884
                break;
849
885
            case NAMESPACE:
850
 
                tokAdd(new TokAxisNamespace());
 
886
                tokAdd(Token::TOK_AXIS_NAMESPACE);
 
887
                break;
851
888
            case PARENT:
852
 
                tokAdd(new TokAxisParent());
 
889
                tokAdd(Token::TOK_AXIS_PARENT);
 
890
                break;
853
891
            case PRECEDING_SIBLING:
854
 
                tokAdd(new TokAxisPrecedingSibling());
 
892
                tokAdd(Token::TOK_AXIS_PRECEDING_SIBLING);
 
893
                break;
855
894
            case PRECEDING:
856
 
                tokAdd(new TokAxisPreceding());
 
895
                tokAdd(Token::TOK_AXIS_PRECEDING);
 
896
                break;
857
897
            case SELF:
858
 
                tokAdd(new TokAxisSelf());
 
898
                tokAdd(Token::TOK_AXIS_SELF);
 
899
                break;
859
900
            default:
860
901
                {
861
902
                error("unknown axis type %d", axisType);
917
958
    if (t.getType() == NAME_TEST)
918
959
        {
919
960
        p++;
920
 
        tokAdd(new TokNameTest(t.getStringValue()));
 
961
        tokAdd(Token::TOK_NAME_TEST, t.getStringValue());
921
962
        return p;
922
963
        }
923
964
    if (t.getType() == NODE_TYPE)
1110
1151
 
1111
1152
    if (lexTokType(p) == LITERAL)
1112
1153
        {
1113
 
        tokens.add(new TokStr(lexTok(p).getStringValue()));
 
1154
        tokAdd(Token::TOK_STR, lexTok(p).getStringValue());
1114
1155
        p++;
1115
1156
        return p;
1116
1157
        }
1117
1158
 
1118
1159
    if (lexTokType(p) == NUMBER)
1119
1160
        {
1120
 
        tokens.add(new TokFloat(lexTok(p).getDoubleValue()));
 
1161
        tokAdd(Token::TOK_FLOAT, lexTok(p).getDoubleValue());
1121
1162
        p++;
1122
1163
        return p;
1123
1164
        }
1195
1236
 
1196
1237
    // Function names from http://www.w3.org/TR/xpath#NT-FunctionName
1197
1238
    if (name == "last")
1198
 
        tokens.add(new TokFuncLast());
 
1239
        tokAdd(Token::TOK_FUNC_LAST);
1199
1240
    else if (name == "position")
1200
 
        tokens.add(new TokFuncPosition());
 
1241
        tokAdd(Token::TOK_FUNC_POSITION);
1201
1242
    else if (name == "count")
1202
 
        tokens.add(new TokFuncCount());
 
1243
        tokAdd(Token::TOK_FUNC_COUNT);
1203
1244
    else if (name == "id")
1204
 
        tokens.add(new TokFuncId());
 
1245
        tokAdd(Token::TOK_FUNC_ID);
1205
1246
    else if (name == "local-name")
1206
 
        tokens.add(new TokFuncLocalName());
 
1247
        tokAdd(Token::TOK_FUNC_LOCAL_NAME);
1207
1248
    else if (name == "namespace-uri")
1208
 
        tokens.add(new TokFuncNamespaceUri());
 
1249
        tokAdd(Token::TOK_FUNC_NAMESPACE_URI);
1209
1250
    else if (name == "name")
1210
 
        tokens.add(new TokFuncName());
 
1251
        tokAdd(Token::TOK_FUNC_NAME);
1211
1252
    else if (name == "string")
1212
 
        tokens.add(new TokFuncString());
 
1253
        tokAdd(Token::TOK_FUNC_STRING);
1213
1254
    else if (name == "concat")
1214
 
        tokens.add(new TokFuncConcat());
 
1255
        tokAdd(Token::TOK_FUNC_CONCAT);
1215
1256
    else if (name == "starts-with")
1216
 
        tokens.add(new TokFuncStartsWith());
 
1257
        tokAdd(Token::TOK_FUNC_STARTS_WITH);
1217
1258
    else if (name == "contains")
1218
 
        tokens.add(new TokFuncContains());
 
1259
        tokAdd(Token::TOK_FUNC_CONTAINS);
1219
1260
    else if (name == "substring-before")
1220
 
        tokens.add(new TokFuncSubstringBefore());
 
1261
        tokAdd(Token::TOK_FUNC_SUBSTRING_BEFORE);
1221
1262
    else if (name == "substring-after")
1222
 
        tokens.add(new TokFuncSubstringAfter());
 
1263
        tokAdd(Token::TOK_FUNC_SUBSTRING_AFTER);
1223
1264
    else if (name == "substring")
1224
 
        tokens.add(new TokFuncSubstring());
 
1265
        tokAdd(Token::TOK_FUNC_SUBSTRING);
1225
1266
    else if (name == "string-length")
1226
 
        tokens.add(new TokFuncStringLength());
 
1267
        tokAdd(Token::TOK_FUNC_STRING_LENGTH);
1227
1268
    else if (name == "normalize-space")
1228
 
        tokens.add(new TokFuncNormalizeSpace());
 
1269
        tokAdd(Token::TOK_FUNC_NORMALIZE_SPACE);
1229
1270
    else if (name == "translate")
1230
 
        tokens.add(new TokFuncTranslate());
 
1271
        tokAdd(Token::TOK_FUNC_TRANSLATE);
1231
1272
    else if (name == "boolean")
1232
 
        tokens.add(new TokFuncBoolean());
 
1273
        tokAdd(Token::TOK_FUNC_BOOLEAN);
1233
1274
    else if (name == "not")
1234
 
        tokens.add(new TokFuncNot());
 
1275
        tokAdd(Token::TOK_FUNC_NOT);
1235
1276
    else if (name == "true")
1236
 
        tokens.add(new TokFuncTrue());
 
1277
        tokAdd(Token::TOK_FUNC_TRUE);
1237
1278
    else if (name == "false")
1238
 
        tokens.add(new TokFuncFalse());
 
1279
        tokAdd(Token::TOK_FUNC_FALSE);
1239
1280
    else if (name == "lang")
1240
 
        tokens.add(new TokFuncLang());
 
1281
        tokAdd(Token::TOK_FUNC_LANG);
1241
1282
    else if (name == "number")
1242
 
        tokens.add(new TokFuncNumber());
 
1283
        tokAdd(Token::TOK_FUNC_NUMBER);
1243
1284
    else if (name == "sum")
1244
 
        tokens.add(new TokFuncSum());
 
1285
        tokAdd(Token::TOK_FUNC_SUM);
1245
1286
    else if (name == "floor")
1246
 
        tokens.add(new TokFuncFloor());
 
1287
        tokAdd(Token::TOK_FUNC_FLOOR);
1247
1288
    else if (name == "ceiling")
1248
 
        tokens.add(new TokFuncCeiling());
 
1289
        tokAdd(Token::TOK_FUNC_CEILING);
1249
1290
    else if (name == "round")
1250
 
        tokens.add(new TokFuncRound());
 
1291
        tokAdd(Token::TOK_FUNC_ROUND);
1251
1292
    else
1252
1293
        {
1253
1294
        error("unknown function name:'%s'", name.c_str());
1302
1343
            error("OR (|) requires union expression on the left");
1303
1344
            return -1;
1304
1345
            }
1305
 
        tokens.add(new TokUnion());
 
1346
        tokAdd(Token::TOK_UNION);
1306
1347
        p = p2;
1307
1348
        }
1308
1349
    return p;
1446
1487
            p = p2;
1447
1488
            return p;
1448
1489
            }
1449
 
        tokens.add(new TokOr());
 
1490
        tokAdd(Token::TOK_OR);
1450
1491
        return p;
1451
1492
        }
1452
1493
 
1485
1526
            p = p2;
1486
1527
            return p;
1487
1528
            }
1488
 
        tokens.add(new TokAnd());
 
1529
        tokAdd(Token::TOK_AND);
1489
1530
        return p;
1490
1531
        }
1491
1532
 
1522
1563
                error("Equality expression expected after ==");
1523
1564
                return -1;
1524
1565
                }
1525
 
            tokens.add(new TokEquals());
 
1566
            tokAdd(Token::TOK_EQUALS);
1526
1567
            p = p2;
1527
1568
            return p;
1528
1569
            }
1536
1577
                error("Equality expression expected after !=");
1537
1578
                return -1;
1538
1579
                }
1539
 
            tokens.add(new TokNotEquals());
 
1580
            tokAdd(Token::TOK_NOT_EQUALS);
1540
1581
            p = p2;
1541
1582
            return p;
1542
1583
            }
1580
1621
                error("Relational expression after '>'");
1581
1622
                return -1;
1582
1623
                }
1583
 
            tokens.add(new TokGreaterThan());
 
1624
            tokAdd(Token::TOK_GREATER_THAN);
1584
1625
            p = p2;
1585
1626
            return p;
1586
1627
            }
1593
1634
                error("Relational expression after '<'");
1594
1635
                return -1;
1595
1636
                }
1596
 
            tokens.add(new TokLessThan());
 
1637
            tokAdd(Token::TOK_LESS_THAN);
1597
1638
            p = p2;
1598
1639
            return p;
1599
1640
            }
1606
1647
                error("Relational expression after '>='");
1607
1648
                return -1;
1608
1649
                }
1609
 
            tokens.add(new TokGreaterThanEquals());
 
1650
            tokAdd(Token::TOK_GREATER_THAN_EQUALS);
1610
1651
            p = p2;
1611
1652
            return p;
1612
1653
            }
1619
1660
                error("Relational expression after '<='");
1620
1661
                return -1;
1621
1662
                }
1622
 
            tokens.add(new TokLessThanEquals());
 
1663
            tokAdd(Token::TOK_LESS_THAN_EQUALS);
1623
1664
            p = p2;
1624
1665
            return p;
1625
1666
            }
1662
1703
                error("Additive expression after '+'");
1663
1704
                return -1;
1664
1705
                }
1665
 
            tokens.add(new TokPlus());
 
1706
            tokAdd(Token::TOK_MINUS);
1666
1707
            p = p2;
1667
1708
            return p;
1668
1709
            }
1675
1716
                error("Additive expression after '-'");
1676
1717
                return -1;
1677
1718
                }
1678
 
            tokens.add(new TokMinus());
 
1719
            tokAdd(Token::TOK_MINUS);
1679
1720
            p = p2;
1680
1721
            return p;
1681
1722
            }
1719
1760
                error("Multiplicative expression after '*'");
1720
1761
                return -1;
1721
1762
                }
1722
 
            tokens.add(new TokMul());
 
1763
            tokAdd(Token::TOK_MUL);
1723
1764
            p = p2;
1724
1765
            return p;
1725
1766
            }
1733
1774
                error("Multiplicative expression after 'div'");
1734
1775
                return -1;
1735
1776
                }
1736
 
            tokens.add(new TokDiv());
 
1777
            tokAdd(Token::TOK_DIV);
1737
1778
            p = p2;
1738
1779
            return p;
1739
1780
            }
1747
1788
                error("Multiplicative expression after 'mod'");
1748
1789
                return -1;
1749
1790
                }
1750
 
            tokens.add(new TokMod());
 
1791
            tokAdd(Token::TOK_MOD);
1751
1792
            p = p2;
1752
1793
            return p;
1753
1794
            }
1790
1831
            error("Unary expression after '-'");
1791
1832
            return -1;
1792
1833
            }
1793
 
        tokens.add(new TokNeg());
 
1834
            tokAdd(Token::TOK_NEG);
1794
1835
        p = p2;
1795
1836
        return p;
1796
1837
        }
2010
2051
 * This wraps the two-step call to parse(), then execute() to get a NodeList
2011
2052
 * of matching DOM nodes
2012
2053
 */
2013
 
NodeList XPathParser::evaluate(const Node *root,
 
2054
NodeList XPathParser::evaluate(const NodePtr root,
2014
2055
                               const DOMString &xpathString)
2015
2056
{
2016
2057
    NodeList list;
2027
2068
 
2028
2069
    //### Execute the token list
2029
2070
    TokenExecutor executor;
2030
 
    list = executor.execute(tokens, root);
 
2071
    NodeList results;
 
2072
    if (!executor.execute(tokens, root, results))
 
2073
        {
 
2074
        //error
 
2075
        }
2031
2076
 
2032
 
    return list;
 
2077
    return results;
2033
2078
}
2034
2079
 
2035
2080