OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 list->Rewind(0); | 1643 list->Rewind(0); |
1644 list->Add(CharacterRange(10, 19)); | 1644 list->Add(CharacterRange(10, 19)); |
1645 list->Add(CharacterRange(21, 30)); | 1645 list->Add(CharacterRange(21, 30)); |
1646 list->Add(CharacterRange(20, 20)); | 1646 list->Add(CharacterRange(20, 20)); |
1647 set.Canonicalize(); | 1647 set.Canonicalize(); |
1648 ASSERT_EQ(1, list->length()); | 1648 ASSERT_EQ(1, list->length()); |
1649 ASSERT_EQ(10, list->at(0).from()); | 1649 ASSERT_EQ(10, list->at(0).from()); |
1650 ASSERT_EQ(30, list->at(0).to()); | 1650 ASSERT_EQ(30, list->at(0).to()); |
1651 } | 1651 } |
1652 | 1652 |
| 1653 // Checks whether a character is in the set represented by a list of ranges. |
| 1654 static bool CharacterInSet(ZoneList<CharacterRange>* set, uc16 value) { |
| 1655 for (int i = 0; i < set->length(); i++) { |
| 1656 CharacterRange range = set->at(i); |
| 1657 if (range.from() <= value && value <= range.to()) { |
| 1658 return true; |
| 1659 } |
| 1660 } |
| 1661 return false; |
| 1662 } |
| 1663 |
| 1664 TEST(CharacterRangeMerge) { |
| 1665 ZoneScope zone_scope(DELETE_ON_EXIT); |
| 1666 ZoneList<CharacterRange> l1(4); |
| 1667 ZoneList<CharacterRange> l2(4); |
| 1668 // Create all combinations of intersections of ranges, both singletons and |
| 1669 // longer. |
| 1670 |
| 1671 int offset = 0; |
| 1672 |
| 1673 // The five kinds of singleton intersections: |
| 1674 // X |
| 1675 // Y - outside before |
| 1676 // Y - outside touching start |
| 1677 // Y - overlap |
| 1678 // Y - outside touching end |
| 1679 // Y - outside after |
| 1680 |
| 1681 for (int i = 0; i < 5; i++) { |
| 1682 l1.Add(CharacterRange::Singleton(offset + 2)); |
| 1683 l2.Add(CharacterRange::Singleton(offset + i)); |
| 1684 offset += 6; |
| 1685 } |
| 1686 |
| 1687 // The seven kinds of singleton/non-singleton intersections: |
| 1688 // XXX |
| 1689 // Y - outside before |
| 1690 // Y - outside touching start |
| 1691 // Y - inside touching start |
| 1692 // Y - entirely inside |
| 1693 // Y - inside touching end |
| 1694 // Y - outside touching end |
| 1695 // Y - disjoint after |
| 1696 |
| 1697 for (int i = 0; i < 7; i++) { |
| 1698 l1.Add(CharacterRange::Range(offset + 2, offset + 4)); |
| 1699 l2.Add(CharacterRange::Singleton(offset + i)); |
| 1700 offset += 8; |
| 1701 } |
| 1702 |
| 1703 // The eleven kinds of non-singleton intersections: |
| 1704 // |
| 1705 // XXXXXXXX |
| 1706 // YYYY - outside before. |
| 1707 // YYYY - outside touching start. |
| 1708 // YYYY - overlapping start |
| 1709 // YYYY - inside touching start |
| 1710 // YYYY - entirely inside |
| 1711 // YYYY - inside touching end |
| 1712 // YYYY - overlapping end |
| 1713 // YYYY - outside touching end |
| 1714 // YYYY - outside after |
| 1715 // YYYYYYYY - identical |
| 1716 // YYYYYYYYYYYY - containing entirely. |
| 1717 |
| 1718 for (int i = 0; i < 9; i++) { |
| 1719 l1.Add(CharacterRange::Range(offset + 6, offset + 15)); // Length 8. |
| 1720 l2.Add(CharacterRange::Range(offset + 2 * i, offset + 2 * i + 3)); |
| 1721 offset += 22; |
| 1722 } |
| 1723 l1.Add(CharacterRange::Range(offset + 6, offset + 15)); |
| 1724 l2.Add(CharacterRange::Range(offset + 6, offset + 15)); |
| 1725 offset += 22; |
| 1726 l1.Add(CharacterRange::Range(offset + 6, offset + 15)); |
| 1727 l2.Add(CharacterRange::Range(offset + 4, offset + 17)); |
| 1728 offset += 22; |
| 1729 |
| 1730 // Different kinds of multi-range overlap: |
| 1731 // XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX |
| 1732 // YYYY Y YYYY Y YYYY Y YYYY Y YYYY Y YYYY Y |
| 1733 |
| 1734 l1.Add(CharacterRange::Range(offset, offset + 21)); |
| 1735 l1.Add(CharacterRange::Range(offset + 31, offset + 52)); |
| 1736 for (int i = 0; i < 6; i++) { |
| 1737 l2.Add(CharacterRange::Range(offset + 2, offset + 5)); |
| 1738 l2.Add(CharacterRange::Singleton(offset + 8)); |
| 1739 offset += 9; |
| 1740 } |
| 1741 |
| 1742 ASSERT(CharacterRange::IsCanonical(&l1)); |
| 1743 ASSERT(CharacterRange::IsCanonical(&l2)); |
| 1744 |
| 1745 ZoneList<CharacterRange> first_only(4); |
| 1746 ZoneList<CharacterRange> second_only(4); |
| 1747 ZoneList<CharacterRange> both(4); |
| 1748 |
| 1749 // Merge one direction. |
| 1750 CharacterRange::Merge(&l1, &l2, &first_only, &second_only, &both); |
| 1751 |
| 1752 CHECK(CharacterRange::IsCanonical(&first_only)); |
| 1753 CHECK(CharacterRange::IsCanonical(&second_only)); |
| 1754 CHECK(CharacterRange::IsCanonical(&both)); |
| 1755 |
| 1756 for (uc16 i = 0; i < offset; i++) { |
| 1757 bool in_first = CharacterInSet(&l1, i); |
| 1758 bool in_second = CharacterInSet(&l2, i); |
| 1759 CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); |
| 1760 CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); |
| 1761 CHECK((in_first && in_second) == CharacterInSet(&both, i)); |
| 1762 } |
| 1763 |
| 1764 first_only.Clear(); |
| 1765 second_only.Clear(); |
| 1766 both.Clear(); |
| 1767 |
| 1768 // Merge other direction. |
| 1769 CharacterRange::Merge(&l2, &l1, &second_only, &first_only, &both); |
| 1770 |
| 1771 CHECK(CharacterRange::IsCanonical(&first_only)); |
| 1772 CHECK(CharacterRange::IsCanonical(&second_only)); |
| 1773 CHECK(CharacterRange::IsCanonical(&both)); |
| 1774 |
| 1775 for (uc16 i = 0; i < offset; i++) { |
| 1776 bool in_first = CharacterInSet(&l1, i); |
| 1777 bool in_second = CharacterInSet(&l2, i); |
| 1778 CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); |
| 1779 CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); |
| 1780 CHECK((in_first && in_second) == CharacterInSet(&both, i)); |
| 1781 } |
| 1782 |
| 1783 first_only.Clear(); |
| 1784 second_only.Clear(); |
| 1785 both.Clear(); |
| 1786 |
| 1787 // Merge but don't record all combinations. |
| 1788 CharacterRange::Merge(&l1, &l2, NULL, NULL, &both); |
| 1789 |
| 1790 CHECK(CharacterRange::IsCanonical(&both)); |
| 1791 |
| 1792 for (uc16 i = 0; i < offset; i++) { |
| 1793 bool in_first = CharacterInSet(&l1, i); |
| 1794 bool in_second = CharacterInSet(&l2, i); |
| 1795 CHECK((in_first && in_second) == CharacterInSet(&both, i)); |
| 1796 } |
| 1797 |
| 1798 // Merge into same set. |
| 1799 ZoneList<CharacterRange> all(4); |
| 1800 CharacterRange::Merge(&l1, &l2, &all, &all, &all); |
| 1801 |
| 1802 CHECK(CharacterRange::IsCanonical(&all)); |
| 1803 |
| 1804 for (uc16 i = 0; i < offset; i++) { |
| 1805 bool in_first = CharacterInSet(&l1, i); |
| 1806 bool in_second = CharacterInSet(&l2, i); |
| 1807 CHECK((in_first || in_second) == CharacterInSet(&all, i)); |
| 1808 } |
| 1809 } |
1653 | 1810 |
1654 | 1811 |
1655 TEST(Graph) { | 1812 TEST(Graph) { |
1656 V8::Initialize(NULL); | 1813 V8::Initialize(NULL); |
1657 Execute("\\b\\w+\\b", false, true, true); | 1814 Execute("\\b\\w+\\b", false, true, true); |
1658 } | 1815 } |
OLD | NEW |