(StringIterator t, CharClass cc)
| 1545 | // flag is not enabled; |t.pos()| is not advanced in this case. |
| 1546 | // Indicates error by throwing PatternSyntaxException. |
| 1547 | private boolean parseUnicodeClass(StringIterator t, CharClass cc) throws PatternSyntaxException { |
| 1548 | int startPos = t.pos(); |
| 1549 | if ((flags & RE2.UNICODE_GROUPS) == 0 || (!t.lookingAt("\\p") && !t.lookingAt("\\P"))) { |
| 1550 | return false; |
| 1551 | } |
| 1552 | t.skip(1); // '\\' |
| 1553 | // Committed to parse or throw exception. |
| 1554 | int sign = +1; |
| 1555 | int c = t.pop(); // 'p' or 'P' |
| 1556 | if (c == 'P') { |
| 1557 | sign = -1; |
| 1558 | } |
| 1559 | if (!t.more()) { |
| 1560 | t.rewindTo(startPos); |
| 1561 | throw new PatternSyntaxException(ERR_INVALID_CHAR_RANGE, t.rest()); |
| 1562 | } |
| 1563 | c = t.pop(); |
| 1564 | String name; |
| 1565 | if (c != '{') { |
| 1566 | // Single-letter name. |
| 1567 | name = Utils.runeToString(c); |
| 1568 | } else { |
| 1569 | // Name is in braces. |
| 1570 | String rest = t.rest(); |
| 1571 | int end = rest.indexOf('}'); |
| 1572 | if (end < 0) { |
| 1573 | t.rewindTo(startPos); |
| 1574 | throw new PatternSyntaxException(ERR_INVALID_CHAR_RANGE, t.rest()); |
| 1575 | } |
| 1576 | name = rest.substring(0, end); // e.g. "Han" |
| 1577 | t.skipString(name); |
| 1578 | t.skip(1); // '}' |
| 1579 | // Don't use skip(end) because it assumes UTF-16 coding, and |
| 1580 | // StringIterator doesn't guarantee that. |
| 1581 | } |
| 1582 | |
| 1583 | // Group can have leading negation too. |
| 1584 | // \p{^Han} == \P{Han}, \P{^Han} == \p{Han}. |
| 1585 | if (!name.isEmpty() && name.charAt(0) == '^') { |
| 1586 | sign = -sign; |
| 1587 | name = name.substring(1); |
| 1588 | } |
| 1589 | |
| 1590 | Pair<int[][], int[][]> pair = unicodeTable(name); |
| 1591 | if (pair == null) { |
| 1592 | throw new PatternSyntaxException(ERR_INVALID_CHAR_RANGE, t.from(startPos)); |
| 1593 | } |
| 1594 | int[][] tab = pair.first; |
| 1595 | int[][] fold = pair.second; // fold-equivalent table |
| 1596 | |
| 1597 | // Variation of CharClass.appendGroup() for tables. |
| 1598 | if ((flags & RE2.FOLD_CASE) == 0 || fold == null) { |
| 1599 | cc.appendTableWithSign(tab, sign); |
| 1600 | } else { |
| 1601 | // Merge and clean tab and fold in a temporary buffer. |
| 1602 | // This is necessary for the negative case and just tidy |
| 1603 | // for the positive case. |
| 1604 | int[] tmp = new CharClass().appendTable(tab).appendTable(fold).cleanClass().toArray(); |
no test coverage detected