Details
Details
- Reviewers
pulkit - Group Reviewers
hg-reviewers - Commits
- rHG57af5ee15b35: linelog: port to Python 3
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
pulkit |
hg-reviewers |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | contrib/python3-whitelist (1 line) | |||
M | mercurial/linelog.py (14 lines) | |||
M | tests/test-linelog.py (42 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
Augie Fackler | Aug 1 2018, 11:25 PM |
test-known.t | test-known.t | ||||
test-largefiles-cache.t | test-largefiles-cache.t | ||||
test-largefiles-misc.t | test-largefiles-misc.t | ||||
test-largefiles-small-disk.t | test-largefiles-small-disk.t | ||||
test-largefiles-update.t | test-largefiles-update.t | ||||
test-largefiles.t | test-largefiles.t | ||||
test-lfs-largefiles.t | test-lfs-largefiles.t | ||||
test-lfs-pointer.py | test-lfs-pointer.py | ||||
test-linelog.py | |||||
test-linerange.py | test-linerange.py | ||||
test-locate.t | test-locate.t | ||||
test-lock-badness.t | test-lock-badness.t | ||||
test-log-linerange.t | test-log-linerange.t | ||||
test-log.t | test-log.t | ||||
test-logexchange.t | test-logexchange.t | ||||
test-lrucachedict.py | test-lrucachedict.py | ||||
test-mactext.t | test-mactext.t |
class _jge(_llinstruction): | class _jge(_llinstruction): | ||||
"""If the current rev is greater than or equal to op1, jump to op2.""" | """If the current rev is greater than or equal to op1, jump to op2.""" | ||||
def __init__(self, op1, op2): | def __init__(self, op1, op2): | ||||
self._cmprev = op1 | self._cmprev = op1 | ||||
self._target = op2 | self._target = op2 | ||||
def __str__(self): | def __str__(self): | ||||
return 'JGE %d %d' % (self._cmprev, self._target) | return r'JGE %d %d' % (self._cmprev, self._target) | ||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return (type(self) == type(other) | return (type(self) == type(other) | ||||
and self._cmprev == other._cmprev | and self._cmprev == other._cmprev | ||||
and self._target == other._target) | and self._target == other._target) | ||||
def encode(self): | def encode(self): | ||||
return _llentry.pack(self._cmprev << 2, self._target) | return _llentry.pack(self._cmprev << 2, self._target) | ||||
def execute(self, rev, pc, emit): | def execute(self, rev, pc, emit): | ||||
if rev >= self._cmprev: | if rev >= self._cmprev: | ||||
return self._target | return self._target | ||||
return pc + 1 | return pc + 1 | ||||
class _jump(_llinstruction): | class _jump(_llinstruction): | ||||
"""Unconditional jumps are expressed as a JGE with op1 set to 0.""" | """Unconditional jumps are expressed as a JGE with op1 set to 0.""" | ||||
def __init__(self, op1, op2): | def __init__(self, op1, op2): | ||||
if op1 != 0: | if op1 != 0: | ||||
raise LineLogError("malformed JUMP, op1 must be 0, got %d" % op1) | raise LineLogError("malformed JUMP, op1 must be 0, got %d" % op1) | ||||
self._target = op2 | self._target = op2 | ||||
def __str__(self): | def __str__(self): | ||||
return 'JUMP %d' % (self._target) | return r'JUMP %d' % (self._target) | ||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return (type(self) == type(other) | return (type(self) == type(other) | ||||
and self._target == other._target) | and self._target == other._target) | ||||
def encode(self): | def encode(self): | ||||
return _llentry.pack(0, self._target) | return _llentry.pack(0, self._target) | ||||
def execute(self, rev, pc, emit): | def execute(self, rev, pc, emit): | ||||
return self._target | return self._target | ||||
class _eof(_llinstruction): | class _eof(_llinstruction): | ||||
"""EOF is expressed as a JGE that always jumps to 0.""" | """EOF is expressed as a JGE that always jumps to 0.""" | ||||
def __init__(self, op1, op2): | def __init__(self, op1, op2): | ||||
if op1 != 0: | if op1 != 0: | ||||
raise LineLogError("malformed EOF, op1 must be 0, got %d" % op1) | raise LineLogError("malformed EOF, op1 must be 0, got %d" % op1) | ||||
if op2 != 0: | if op2 != 0: | ||||
raise LineLogError("malformed EOF, op2 must be 0, got %d" % op2) | raise LineLogError("malformed EOF, op2 must be 0, got %d" % op2) | ||||
def __str__(self): | def __str__(self): | ||||
return 'EOF' | return r'EOF' | ||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return type(self) == type(other) | return type(self) == type(other) | ||||
def encode(self): | def encode(self): | ||||
return _llentry.pack(0, 0) | return _llentry.pack(0, 0) | ||||
def execute(self, rev, pc, emit): | def execute(self, rev, pc, emit): | ||||
return None | return None | ||||
class _jl(_llinstruction): | class _jl(_llinstruction): | ||||
"""If the current rev is less than op1, jump to op2.""" | """If the current rev is less than op1, jump to op2.""" | ||||
def __init__(self, op1, op2): | def __init__(self, op1, op2): | ||||
self._cmprev = op1 | self._cmprev = op1 | ||||
self._target = op2 | self._target = op2 | ||||
def __str__(self): | def __str__(self): | ||||
return 'JL %d %d' % (self._cmprev, self._target) | return r'JL %d %d' % (self._cmprev, self._target) | ||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return (type(self) == type(other) | return (type(self) == type(other) | ||||
and self._cmprev == other._cmprev | and self._cmprev == other._cmprev | ||||
and self._target == other._target) | and self._target == other._target) | ||||
def encode(self): | def encode(self): | ||||
return _llentry.pack(1 | (self._cmprev << 2), self._target) | return _llentry.pack(1 | (self._cmprev << 2), self._target) | ||||
def execute(self, rev, pc, emit): | def execute(self, rev, pc, emit): | ||||
if rev < self._cmprev: | if rev < self._cmprev: | ||||
return self._target | return self._target | ||||
return pc + 1 | return pc + 1 | ||||
class _line(_llinstruction): | class _line(_llinstruction): | ||||
"""Emit a line.""" | """Emit a line.""" | ||||
def __init__(self, op1, op2): | def __init__(self, op1, op2): | ||||
# This line was introduced by this revision number. | # This line was introduced by this revision number. | ||||
self._rev = op1 | self._rev = op1 | ||||
# This line had the specified line number in the introducing revision. | # This line had the specified line number in the introducing revision. | ||||
self._origlineno = op2 | self._origlineno = op2 | ||||
def __str__(self): | def __str__(self): | ||||
return 'LINE %d %d' % (self._rev, self._origlineno) | return r'LINE %d %d' % (self._rev, self._origlineno) | ||||
def __eq__(self, other): | def __eq__(self, other): | ||||
return (type(self) == type(other) | return (type(self) == type(other) | ||||
and self._rev == other._rev | and self._rev == other._rev | ||||
and self._origlineno == other._origlineno) | and self._origlineno == other._origlineno) | ||||
def encode(self): | def encode(self): | ||||
return _llentry.pack(2 | (self._rev << 2), self._origlineno) | return _llentry.pack(2 | (self._rev << 2), self._origlineno) | ||||
and self._program == other._program | and self._program == other._program | ||||
and self._maxrev == other._maxrev) | and self._maxrev == other._maxrev) | ||||
def __repr__(self): | def __repr__(self): | ||||
return '<linelog at %s: maxrev=%d size=%d>' % ( | return '<linelog at %s: maxrev=%d size=%d>' % ( | ||||
hex(id(self)), self._maxrev, len(self._program)) | hex(id(self)), self._maxrev, len(self._program)) | ||||
def debugstr(self): | def debugstr(self): | ||||
fmt = '%%%dd %%s' % len(str(len(self._program))) | fmt = r'%%%dd %%s' % len(str(len(self._program))) | ||||
return '\n'.join( | return pycompat.sysstr('\n').join( | ||||
fmt % (idx, i) for idx, i in enumerate(self._program[1:], 1)) | fmt % (idx, i) for idx, i in enumerate(self._program[1:], 1)) | ||||
@classmethod | @classmethod | ||||
def fromdata(cls, buf): | def fromdata(cls, buf): | ||||
if len(buf) % _llentry.size != 0: | if len(buf) % _llentry.size != 0: | ||||
raise LineLogError( | raise LineLogError( | ||||
"invalid linelog buffer size %d (must be a multiple of %d)" % ( | "invalid linelog buffer size %d (must be a multiple of %d)" % ( | ||||
len(buf), _llentry.size)) | len(buf), _llentry.size)) |
] | ] | ||||
ll = linelog.linelog(program, maxrev=100) | ll = linelog.linelog(program, maxrev=100) | ||||
enc = ll.encode() | enc = ll.encode() | ||||
# round-trips okay | # round-trips okay | ||||
self.assertEqual(linelog.linelog.fromdata(enc)._program, ll._program) | self.assertEqual(linelog.linelog.fromdata(enc)._program, ll._program) | ||||
self.assertEqual(linelog.linelog.fromdata(enc), ll) | self.assertEqual(linelog.linelog.fromdata(enc), ll) | ||||
# This encoding matches the encoding used by hg-experimental's | # This encoding matches the encoding used by hg-experimental's | ||||
# linelog file, or is supposed to if it doesn't. | # linelog file, or is supposed to if it doesn't. | ||||
self.assertEqual(enc, ('\x00\x00\x01\x90\x00\x00\x00\x06' | self.assertEqual(enc, (b'\x00\x00\x01\x90\x00\x00\x00\x06' | ||||
'\x00\x00\x00\xa4\x00\x00\x00*' | b'\x00\x00\x00\xa4\x00\x00\x00*' | ||||
'\x00\x00\x00\x00\x00\x00\x00+' | b'\x00\x00\x00\x00\x00\x00\x00+' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x00' | b'\x00\x00\x00\x00\x00\x00\x00\x00' | ||||
'\x00\x00\x00\xb1\x00\x00\x00-' | b'\x00\x00\x00\xb1\x00\x00\x00-' | ||||
'\x00\x00\x00\xba\x00\x00\x00/')) | b'\x00\x00\x00\xba\x00\x00\x00/')) | ||||
def testsimpleedits(self): | def testsimpleedits(self): | ||||
ll = linelog.linelog() | ll = linelog.linelog() | ||||
# Initial revision: add lines 0, 1, and 2 | # Initial revision: add lines 0, 1, and 2 | ||||
ll.replacelines(1, 0, 0, 0, 3) | ll.replacelines(1, 0, 0, 0, 3) | ||||
self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)], | self.assertEqual([(l.rev, l.linenum) for l in ll.annotate(1)], | ||||
[(1, 0), | [(1, 0), | ||||
(1, 1), | (1, 1), | ||||
(2, 1), | (2, 1), | ||||
(1, 1), | (1, 1), | ||||
(1, 2), | (1, 2), | ||||
]) | ]) | ||||
def testparseclinelogfile(self): | def testparseclinelogfile(self): | ||||
# This data is what the replacements in testsimpleedits | # This data is what the replacements in testsimpleedits | ||||
# produce when fed to the original linelog.c implementation. | # produce when fed to the original linelog.c implementation. | ||||
data = ('\x00\x00\x00\x0c\x00\x00\x00\x0f' | data = (b'\x00\x00\x00\x0c\x00\x00\x00\x0f' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x02' | b'\x00\x00\x00\x00\x00\x00\x00\x02' | ||||
'\x00\x00\x00\x05\x00\x00\x00\x06' | b'\x00\x00\x00\x05\x00\x00\x00\x06' | ||||
'\x00\x00\x00\x06\x00\x00\x00\x00' | b'\x00\x00\x00\x06\x00\x00\x00\x00' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x07' | b'\x00\x00\x00\x00\x00\x00\x00\x07' | ||||
'\x00\x00\x00\x06\x00\x00\x00\x02' | b'\x00\x00\x00\x06\x00\x00\x00\x02' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x00' | b'\x00\x00\x00\x00\x00\x00\x00\x00' | ||||
'\x00\x00\x00\t\x00\x00\x00\t' | b'\x00\x00\x00\t\x00\x00\x00\t' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x0c' | b'\x00\x00\x00\x00\x00\x00\x00\x0c' | ||||
'\x00\x00\x00\x08\x00\x00\x00\x05' | b'\x00\x00\x00\x08\x00\x00\x00\x05' | ||||
'\x00\x00\x00\x06\x00\x00\x00\x01' | b'\x00\x00\x00\x06\x00\x00\x00\x01' | ||||
'\x00\x00\x00\x00\x00\x00\x00\x05' | b'\x00\x00\x00\x00\x00\x00\x00\x05' | ||||
'\x00\x00\x00\x0c\x00\x00\x00\x05' | b'\x00\x00\x00\x0c\x00\x00\x00\x05' | ||||
'\x00\x00\x00\n\x00\x00\x00\x01' | b'\x00\x00\x00\n\x00\x00\x00\x01' | ||||
'\x00\x00\x00\x00\x00\x00\x00\t') | b'\x00\x00\x00\x00\x00\x00\x00\t') | ||||
llc = linelog.linelog.fromdata(data) | llc = linelog.linelog.fromdata(data) | ||||
self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(1)], | self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(1)], | ||||
[(1, 0), | [(1, 0), | ||||
(1, 1), | (1, 1), | ||||
(1, 2), | (1, 2), | ||||
]) | ]) | ||||
self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(2)], | self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(2)], | ||||
[(1, 0), | [(1, 0), |