⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifile.py

📁 reduced python source for embedded apps
💻 PY
字号:
# Tools for info file processing.# XXX Need to be more careful with reading ahead searching for nodes.import regexpimport string# Exported exceptions.#NoSuchFile = 'no such file'NoSuchNode = 'no such node'# The search path for info files; this is site-specific.# Directory names should end in a partname delimiter,# so they can simply be concatenated to a relative pathname.##INFOPATH = ['', ':Info.Ibrowse:', ':Info:']	# MacINFOPATH = ['', '/usr/local/emacs/info/']	# X11 on UNIX# Tunable constants.#BLOCKSIZE = 512			# Qty to align reads to, if possibleFUZZ = 2*BLOCKSIZE		# Qty to back-up before searching for a nodeCHUNKSIZE = 4*BLOCKSIZE		# Qty to read at once when reading lots of data# Regular expressions used.# Note that it is essential that Python leaves unrecognized backslash# escapes in a string so they can be seen by regexp.compile!#findheader = regexp.compile('\037\014?\n(.*\n)').matchfindescape = regexp.compile('\037').matchparseheader = regexp.compile('[nN]ode:[ \t]*([^\t,\n]*)').matchfindfirstline = regexp.compile('^.*\n').matchfindnode = regexp.compile('[nN]ode:[ \t]*([^\t,\n]*)').matchfindprev = regexp.compile('[pP]rev[ious]*:[ \t]*([^\t,\n]*)').matchfindnext = regexp.compile('[nN]ext:[ \t]*([^\t,\n]*)').matchfindup = regexp.compile('[uU]p:[ \t]*([^\t,\n]*)').matchfindmenu = regexp.compile('^\* [mM]enu:').matchfindmenuitem = regexp.compile( \	'^\* ([^:]+):[ \t]*(:|\([^\t]*\)[^\t,\n.]*|[^:(][^\t,\n.]*)').matchfindfootnote = regexp.compile( \	'\*[nN]ote ([^:]+):[ \t]*(:|[^:][^\t,\n.]*)').matchparsenoderef = regexp.compile('^\((.*)\)(.*)$').match# Get a node and all information pertaining to it.# This doesn't work if there is an indirect tag table,# and in general you are better off using icache.get_node() instead.# Functions get_whole_file() and get_file_node() provide part# functionality used by icache.# Raise NoSuchFile or NoSuchNode as appropriate.#def get_node(curfile, ref):	file, node = parse_ref(curfile, ref)	if node == '*':		return get_whole_file(file)	else:		return get_file_node(file, 0, node)#def get_whole_file(file):	f = try_open(file) # May raise NoSuchFile	text = f.read()	header, menu, footnotes = ('', '', ''), [], []	return file, '*', header, menu, footnotes, text#def get_file_node(file, offset, node):	f = try_open(file) # May raise NoSuchFile	text = find_node(f, offset, node) # May raise NoSuchNode	node, header, menu, footnotes = analyze_node(text)	return file, node, header, menu, footnotes, text# Parse a node reference into a file (possibly default) and node name.# Possible reference formats are: "NODE", "(FILE)", "(FILE)NODE".# Default file is the curfile argument; default node is Top.# A node value of '*' is a special case: the whole file should# be interpreted (by the caller!) as a single node.#def parse_ref(curfile, ref):	match = parsenoderef(ref)	if not match:		file, node = curfile, ref	else:		(a, b), (a1, b1), (a2, b2) = match		file, node = ref[a1:b1], ref[a2:b2]	if not file:		file = curfile # (Is this necessary?)	if not node:		node = 'Top'	return file, node# Extract node name, links, menu and footnotes from the node text.#def analyze_node(text):	#	# Get node name and links from the header line	#	match = findfirstline(text)	if match:		(a, b) = match[0]		line = text[a:b]	else:		line = ''	node = get_it(text, findnode)	prev = get_it(text, findprev)	next = get_it(text, findnext)	up = get_it(text, findup)	#	# Get the menu items, if there is a menu	#	menu = []	match = findmenu(text)	if match:		(a, b) = match[0]		while 1:			match = findmenuitem(text, b)			if not match:				break			(a, b), (a1, b1), (a2, b2) = match			topic, ref = text[a1:b1], text[a2:b2]			if ref == ':':				ref = topic			menu.append((topic, ref))	#	# Get the footnotes	#	footnotes = []	b = 0	while 1:		match = findfootnote(text, b)		if not match:			break		(a, b), (a1, b1), (a2, b2) = match		topic, ref = text[a1:b1], text[a2:b2]		if ref == ':':			ref = topic		footnotes.append((topic, ref))	#	return node, (prev, next, up), menu, footnotes#def get_it(line, matcher):	match = matcher(line)	if not match:		return ''	else:		(a, b), (a1, b1) = match		return line[a1:b1]# Find a node in an open file.# The offset (from the tags table) is a hint about the node's position.# Pass zero if there is no tags table.# Raise NoSuchNode if the node isn't found.# NB: This seeks around in the file.#def find_node(f, offset, node):	node = string.lower(node) # Just to be sure	#	# Position a little before the given offset,	# so we may find the node even if it has moved around	# in the file a little.	#	offset = max(0, ((offset-FUZZ) / BLOCKSIZE) * BLOCKSIZE)	f.seek(offset)	#	# Loop, hunting for a matching node header.	#	while 1:		buf = f.read(CHUNKSIZE)		if not buf:			break		i = 0		while 1:			match = findheader(buf, i)			if match:				(a,b), (a1,b1) = match				start = a1				line = buf[a1:b1]				i = b				match = parseheader(line)				if match:					(a,b), (a1,b1) = match					key = string.lower(line[a1:b1])					if key == node:						# Got it!  Now read the rest.						return read_node(f, buf[start:])			elif findescape(buf, i):				next = f.read(CHUNKSIZE)				if not next:					break				buf = buf + next			else:				break	#	# If we get here, we didn't find it.  Too bad.	#	raise NoSuchNode, node# Finish off getting a node (subroutine for find_node()).# The node begins at the start of buf and may end in buf;# if it doesn't end there, read additional data from f.#def read_node(f, buf):	i = 0	match = findescape(buf, i)	while not match:		next = f.read(CHUNKSIZE)		if not next:			end = len(buf)			break		i = len(buf)		buf = buf + next		match = findescape(buf, i)	else:		# Got a match		(a, b) = match[0]		end = a	# Strip trailing newlines	while end > 0 and buf[end-1] == '\n':		end = end-1	buf = buf[:end]	return buf# Read reverse starting at offset until the beginning of a node is found.# Then return a buffer containing the beginning of the node,# with f positioned just after the buffer.# The buffer will contain at least the full header line of the node;# the caller should finish off with read_node() if it is the right node.# (It is also possible that the buffer extends beyond the node!)# Return an empty string if there is no node before the given offset.#def backup_node(f, offset):	start = max(0, ((offset-CHUNKSIZE) / BLOCKSIZE) * BLOCKSIZE)	end = offset	while start < end:		f.seek(start)		buf = f.read(end-start)		i = 0		hit = -1		while 1:			match = findheader(buf, i)			if match:				(a,b), (a1,b1) = match				hit = a1				i = b			elif end < offset and findescape(buf, i):				next = f.read(min(offset-end, BLOCKSIZE))				if not next:					break				buf = buf + next				end = end + len(next)			else:				break		if hit >= 0:			return buf[hit:]		end = start		start = max(0, end - CHUNKSIZE)	return ''# Make a tag table for the given file by scanning the file.# The file must be open for reading, and positioned at the beginning# (or wherever the hunt for tags must begin; it is read till the end).#def make_tags(f):	tags = {}	while 1:		offset = f.tell()		buf = f.read(CHUNKSIZE)		if not buf:			break		i = 0		while 1:			match = findheader(buf, i)			if match:				(a,b), (a1,b1) = match				start = offset+a1				line = buf[a1:b1]				i = b				match = parseheader(line)				if match:					(a,b), (a1,b1) = match					key = string.lower(line[a1:b1])					if tags.has_key(key):						print 'Duplicate node:',						print key					tags[key] = '', start, line			elif findescape(buf, i):				next = f.read(CHUNKSIZE)				if not next:					break				buf = buf + next			else:				break	return tags# Try to open a file, return a file object if succeeds.# Raise NoSuchFile if the file can't be opened.# Should treat absolute pathnames special.#def try_open(file):	for dir in INFOPATH:		try:			return open(dir + file, 'r')		except IOError:			pass	raise NoSuchFile, file# A little test for the speed of make_tags().#TESTFILE = 'texinfo-1'def test_make_tags():	import time	f = try_open(TESTFILE)	t1 = time.millitimer()	tags = make_tags(f)	t2 = time.millitimer()	print 'Making tag table for', `TESTFILE`, 'took', t2-t1, 'msec.'

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -