import string import color, mode from lex import Grammar, PatternRule, RegionRule from method import Method, Argument from point import Point class HexGrammar(Grammar): rules = [ PatternRule(r'zero', r"00"), PatternRule(r'byte', r'[0-f][0-f]'), ] class Hex(mode.Fundamental): modename = 'Hex' grammar = HexGrammar colors = { 'zero': ('magenta', 'default'), 'byte': ('white', 'default'), } lmargin = 12 rmargin = 18 _ctrans = ['.'] * 256 for c in string.letters + string.digits + string.punctuation + ' ': _ctrans[ord(c)] = c ctrans = ''.join(_ctrans) def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_action_and_bindings(GotoWord(), ('M-g',)) self.add_action(FindStrings()) self.add_action(WhichWord()) # create all the insert actions for the basic text input for c in string.letters + string.digits + string.punctuation: if c in string.hexdigits: self.add_binding('overwrite-char-%s' % c.lower(), c) else: self.del_binding(c) def get_lmargin(self, y, x=0, ended=False, cont=False): lm = self.lmargin if ended: s = ' -------- ' elif x == 0: s = '0x%08x ' % (y * 16) return (s, color.build('cyan', 'default', 'bold')) def get_rmargin(self, y, x=0, ended=False, cont=False): if ended: s = '' else: s = string.translate(self.window.buffer.rawdata[y], self.ctrans) return (s, color.build('green', 'default', 'bold')) class GotoWord(Method): '''Jump to the specified line number''' args = [Argument("wordno", type=type(0), prompt="Goto word: ")] def _execute(self, w, **vargs): n = vargs["wordno"] if n < 0: w.set_error("Negative word counts not supported.") try: x = (n % w.buffer.numwords) * (w.buffer.wordsize + 1) y = n / w.buffer.numwords p = Point(x, y) w.goto(p) except: w.goto_end() class WhichWord(Method): '''Show the current word number''' def _execute(self, w, **vargs): cursor = w.logical_cursor() n = cursor.y * w.buffer.numwords n += cursor.x / (w.buffer.wordsize + 1) w.set_error("Currently in word %s (%s)" % (hex(n), n)) class FindStrings(Method): def _execute(self, w, **vargs): newlines = [] lastline = '' i = 0 for line in w.buffer.lines: lastc = None newline = "" for c in line: if c not in '0123456789abcdefABCDEF': lastc = None elif lastc is None: lastc = c else: char = chr(int(lastc + c, 16)) lastc = None if char in string.whitespace: newline += ' ' elif char in string.letters + string.digits + string.punctuation: newline += char else: newline += '.' if lastc is not None: newline += '.' if i == 3: newlines.append(lastline) lastline = '' else: lastline += newline i = (i + 1) % 4 w.application.data_buffer("*Strings*", '\n'.join(newlines), switch_to=True) install = Hex.install