📄 itags.py
字号:
# Utility module for 'icache.py': interpret tag tables and indirect nodes.# (This module is a bit chatty when confronted with the unexpected.)import regexpimport stringimport ifile# Get the tag table of an open file, as a dictionary.# Seeks around in the file; after reading, the position is undefined.# Return an empty tag table if none is found.#def get_tags(f): # # First see if the last "node" is the end of tag table marker. # f.seek(0, 2) # Seek to EOF end = f.tell() buf = ifile.backup_node(f, end) if not labelmatch(buf, 0, 'end tag table\n'): return {} # No succes # # Next backup to the previous "node" -- the tag table itself. # ###print 'Getting prebuilt tag table...' end = f.tell() - len(buf) buf = ifile.backup_node(f, end) label = 'tag table:\n' if not labelmatch(buf, 0, label): print 'Weird: end tag table marker but no tag table?' print 'Node begins:', `buf[:50]` return {} # # Now read the whole tag table. # end = f.tell() - len(buf) # Do this first! buf = ifile.read_node(f, buf) # # First check for an indirection table. # indirlist = [] if labelmatch(buf, len(label), '(indirect)\n'): indirbuf = ifile.backup_node(f, end) if not labelmatch(indirbuf, 0, 'indirect:\n'): print 'Weird: promised indirection table not found' print 'Node begins:', `indirbuf[:50]` # Carry on. Things probably won't work though. else: indirbuf = ifile.read_node(f, indirbuf) indirlist = parse_indirlist(indirbuf) # # Now parse the tag table. # findtag = regexp.compile('^(.*[nN]ode:[ \t]*(.*))\177([0-9]+)$').match i = 0 tags = {} while 1: match = findtag(buf, i) if not match: break (a,b), (a1,b1), (a2,b2), (a3,b3) = match i = b line = buf[a1:b1] node = string.lower(buf[a2:b2]) offset = eval(buf[a3:b3]) # XXX What if it overflows? if tags.has_key(node): print 'Duplicate key in tag table:', `node` file, offset = map_offset(offset, indirlist) tags[node] = file, offset, line # return tags# Return true if buf[i:] begins with a label, after lower case conversion.# The label argument must be in lower case.#def labelmatch(buf, i, label): return string.lower(buf[i:i+len(label)]) == label# Parse the indirection list.# Return a list of (filename, offset) pairs ready for use.#def parse_indirlist(buf): list = [] findindir = regexp.compile('^(.+):[ \t]*([0-9]+)$').match i = 0 while 1: match = findindir(buf, i) if not match: break (a,b), (a1,b1), (a2,b2) = match file = buf[a1:b1] offset = eval(buf[a2:b2]) # XXX What if this gets overflow? list.append((file, offset)) i = b return list# Map an offset through the indirection list.# Return (filename, new_offset).# If the list is empty, return the given offset and an empty file name.#def map_offset(offset, indirlist): if not indirlist: return '', offset # # XXX This could be done more elegant. # filex, offx = indirlist[0] for i in range(len(indirlist)): file1, off1 = indirlist[i] if i+1 >= len(indirlist): file2, off2 = '', 0x7fffffff else: file2, off2 = indirlist[i+1] if off1 <= offset < off2: # Add offx+2 to compensate for extra header. # No idea whether this is always correct. return file1, offset-off1 + offx+2 # # XXX Shouldn't get here. # print 'Oops, map_offset fell through' return '', offset # Not likely to get good results
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -