| @@ 1689-1764 (lines=76) @@ | ||
| 1686 | return collapsed |
|
| 1687 | ||
| 1688 | ||
| 1689 | def FindEndOfExpressionInLine(line, startpos, stack): |
|
| 1690 | """Find the position just after the end of current parenthesized expression. |
|
| 1691 | ||
| 1692 | Args: |
|
| 1693 | line: a CleansedLines line. |
|
| 1694 | startpos: start searching at this position. |
|
| 1695 | stack: nesting stack at startpos. |
|
| 1696 | ||
| 1697 | Returns: |
|
| 1698 | On finding matching end: (index just after matching end, None) |
|
| 1699 | On finding an unclosed expression: (-1, None) |
|
| 1700 | Otherwise: (-1, new stack at end of this line) |
|
| 1701 | """ |
|
| 1702 | for i in xrange(startpos, len(line)): |
|
| 1703 | char = line[i] |
|
| 1704 | if char in '([{': |
|
| 1705 | # Found start of parenthesized expression, push to expression stack |
|
| 1706 | stack.append(char) |
|
| 1707 | elif char == '<': |
|
| 1708 | # Found potential start of template argument list |
|
| 1709 | if i > 0 and line[i - 1] == '<': |
|
| 1710 | # Left shift operator |
|
| 1711 | if stack and stack[-1] == '<': |
|
| 1712 | stack.pop() |
|
| 1713 | if not stack: |
|
| 1714 | return (-1, None) |
|
| 1715 | elif i > 0 and Search(r'\boperator\s*$', line[0:i]): |
|
| 1716 | # operator<, don't add to stack |
|
| 1717 | continue |
|
| 1718 | else: |
|
| 1719 | # Tentative start of template argument list |
|
| 1720 | stack.append('<') |
|
| 1721 | elif char in ')]}': |
|
| 1722 | # Found end of parenthesized expression. |
|
| 1723 | # |
|
| 1724 | # If we are currently expecting a matching '>', the pending '<' |
|
| 1725 | # must have been an operator. Remove them from expression stack. |
|
| 1726 | while stack and stack[-1] == '<': |
|
| 1727 | stack.pop() |
|
| 1728 | if not stack: |
|
| 1729 | return (-1, None) |
|
| 1730 | if ((stack[-1] == '(' and char == ')') or |
|
| 1731 | (stack[-1] == '[' and char == ']') or |
|
| 1732 | (stack[-1] == '{' and char == '}')): |
|
| 1733 | stack.pop() |
|
| 1734 | if not stack: |
|
| 1735 | return (i + 1, None) |
|
| 1736 | else: |
|
| 1737 | # Mismatched parentheses |
|
| 1738 | return (-1, None) |
|
| 1739 | elif char == '>': |
|
| 1740 | # Found potential end of template argument list. |
|
| 1741 | ||
| 1742 | # Ignore "->" and operator functions |
|
| 1743 | if (i > 0 and |
|
| 1744 | (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))): |
|
| 1745 | continue |
|
| 1746 | ||
| 1747 | # Pop the stack if there is a matching '<'. Otherwise, ignore |
|
| 1748 | # this '>' since it must be an operator. |
|
| 1749 | if stack: |
|
| 1750 | if stack[-1] == '<': |
|
| 1751 | stack.pop() |
|
| 1752 | if not stack: |
|
| 1753 | return (i + 1, None) |
|
| 1754 | elif char == ';': |
|
| 1755 | # Found something that look like end of statements. If we are currently |
|
| 1756 | # expecting a '>', the matching '<' must have been an operator, since |
|
| 1757 | # template argument list should not contain statements. |
|
| 1758 | while stack and stack[-1] == '<': |
|
| 1759 | stack.pop() |
|
| 1760 | if not stack: |
|
| 1761 | return (-1, None) |
|
| 1762 | ||
| 1763 | # Did not find end of expression or unbalanced parentheses on this line |
|
| 1764 | return (-1, stack) |
|
| 1765 | ||
| 1766 | ||
| 1767 | def CloseExpression(clean_lines, linenum, pos): |
|
| @@ 1689-1764 (lines=76) @@ | ||
| 1686 | return collapsed |
|
| 1687 | ||
| 1688 | ||
| 1689 | def FindEndOfExpressionInLine(line, startpos, stack): |
|
| 1690 | """Find the position just after the end of current parenthesized expression. |
|
| 1691 | ||
| 1692 | Args: |
|
| 1693 | line: a CleansedLines line. |
|
| 1694 | startpos: start searching at this position. |
|
| 1695 | stack: nesting stack at startpos. |
|
| 1696 | ||
| 1697 | Returns: |
|
| 1698 | On finding matching end: (index just after matching end, None) |
|
| 1699 | On finding an unclosed expression: (-1, None) |
|
| 1700 | Otherwise: (-1, new stack at end of this line) |
|
| 1701 | """ |
|
| 1702 | for i in xrange(startpos, len(line)): |
|
| 1703 | char = line[i] |
|
| 1704 | if char in '([{': |
|
| 1705 | # Found start of parenthesized expression, push to expression stack |
|
| 1706 | stack.append(char) |
|
| 1707 | elif char == '<': |
|
| 1708 | # Found potential start of template argument list |
|
| 1709 | if i > 0 and line[i - 1] == '<': |
|
| 1710 | # Left shift operator |
|
| 1711 | if stack and stack[-1] == '<': |
|
| 1712 | stack.pop() |
|
| 1713 | if not stack: |
|
| 1714 | return (-1, None) |
|
| 1715 | elif i > 0 and Search(r'\boperator\s*$', line[0:i]): |
|
| 1716 | # operator<, don't add to stack |
|
| 1717 | continue |
|
| 1718 | else: |
|
| 1719 | # Tentative start of template argument list |
|
| 1720 | stack.append('<') |
|
| 1721 | elif char in ')]}': |
|
| 1722 | # Found end of parenthesized expression. |
|
| 1723 | # |
|
| 1724 | # If we are currently expecting a matching '>', the pending '<' |
|
| 1725 | # must have been an operator. Remove them from expression stack. |
|
| 1726 | while stack and stack[-1] == '<': |
|
| 1727 | stack.pop() |
|
| 1728 | if not stack: |
|
| 1729 | return (-1, None) |
|
| 1730 | if ((stack[-1] == '(' and char == ')') or |
|
| 1731 | (stack[-1] == '[' and char == ']') or |
|
| 1732 | (stack[-1] == '{' and char == '}')): |
|
| 1733 | stack.pop() |
|
| 1734 | if not stack: |
|
| 1735 | return (i + 1, None) |
|
| 1736 | else: |
|
| 1737 | # Mismatched parentheses |
|
| 1738 | return (-1, None) |
|
| 1739 | elif char == '>': |
|
| 1740 | # Found potential end of template argument list. |
|
| 1741 | ||
| 1742 | # Ignore "->" and operator functions |
|
| 1743 | if (i > 0 and |
|
| 1744 | (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))): |
|
| 1745 | continue |
|
| 1746 | ||
| 1747 | # Pop the stack if there is a matching '<'. Otherwise, ignore |
|
| 1748 | # this '>' since it must be an operator. |
|
| 1749 | if stack: |
|
| 1750 | if stack[-1] == '<': |
|
| 1751 | stack.pop() |
|
| 1752 | if not stack: |
|
| 1753 | return (i + 1, None) |
|
| 1754 | elif char == ';': |
|
| 1755 | # Found something that look like end of statements. If we are currently |
|
| 1756 | # expecting a '>', the matching '<' must have been an operator, since |
|
| 1757 | # template argument list should not contain statements. |
|
| 1758 | while stack and stack[-1] == '<': |
|
| 1759 | stack.pop() |
|
| 1760 | if not stack: |
|
| 1761 | return (-1, None) |
|
| 1762 | ||
| 1763 | # Did not find end of expression or unbalanced parentheses on this line |
|
| 1764 | return (-1, stack) |
|
| 1765 | ||
| 1766 | ||
| 1767 | def CloseExpression(clean_lines, linenum, pos): |
|