mirror of https://github.com/xemu-project/xemu.git
72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
# Copyright (C) 2020 Red Hat Inc.
|
|
#
|
|
# Authors:
|
|
# Eduardo Habkost <ehabkost@redhat.com>
|
|
#
|
|
# This work is licensed under the terms of the GNU GPL, version 2. See
|
|
# the COPYING file in the top-level directory.
|
|
from typing import *
|
|
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
DBG = logger.debug
|
|
INFO = logger.info
|
|
WARN = logger.warning
|
|
|
|
T = TypeVar('T')
|
|
def opt_compare(a: T, b: T) -> bool:
|
|
"""Compare two values, ignoring mismatches if one of them is None"""
|
|
return (a is None) or (b is None) or (a == b)
|
|
|
|
def merge(a: T, b: T) -> T:
|
|
"""Merge two values if they matched using opt_compare()"""
|
|
assert opt_compare(a, b)
|
|
if a is None:
|
|
return b
|
|
else:
|
|
return a
|
|
|
|
def test_comp_merge():
|
|
assert opt_compare(None, 1) == True
|
|
assert opt_compare(2, None) == True
|
|
assert opt_compare(1, 1) == True
|
|
assert opt_compare(1, 2) == False
|
|
|
|
assert merge(None, None) is None
|
|
assert merge(None, 10) == 10
|
|
assert merge(10, None) == 10
|
|
assert merge(10, 10) == 10
|
|
|
|
|
|
LineNumber = NewType('LineNumber', int)
|
|
ColumnNumber = NewType('ColumnNumber', int)
|
|
class LineAndColumn(NamedTuple):
|
|
line: int
|
|
col: int
|
|
|
|
def __str__(self):
|
|
return '%d:%d' % (self.line, self.col)
|
|
|
|
def line_col(s, position: int) -> LineAndColumn:
|
|
"""Return line and column for a char position in string
|
|
|
|
Character position starts in 0, but lines and columns start in 1.
|
|
"""
|
|
before = s[:position]
|
|
lines = before.split('\n')
|
|
line = len(lines)
|
|
col = len(lines[-1]) + 1
|
|
return LineAndColumn(line, col)
|
|
|
|
def test_line_col():
|
|
assert line_col('abc\ndefg\nhijkl', 0) == (1, 1)
|
|
assert line_col('abc\ndefg\nhijkl', 2) == (1, 3)
|
|
assert line_col('abc\ndefg\nhijkl', 3) == (1, 4)
|
|
assert line_col('abc\ndefg\nhijkl', 4) == (2, 1)
|
|
assert line_col('abc\ndefg\nhijkl', 10) == (3, 2)
|
|
|
|
def not_optional(arg: Optional[T]) -> T:
|
|
assert arg is not None
|
|
return arg
|
|
|
|
__all__ = ['not_optional', 'opt_compare', 'merge', 'line_col', 'LineAndColumn'] |