| # Cache management for info file processing. | 
 | # The function get_node() is the standard interface; | 
 | # its signature is the same as ifile.get_node() but it uses | 
 | # the cache and supports indirect tag tables. | 
 |  | 
 |  | 
 | import string | 
 | import ifile | 
 | from ifile import NoSuchNode, NoSuchFile | 
 | import itags | 
 |  | 
 |  | 
 | # Special hack to save the cache when using reload(). | 
 | # This can just be "cache = {}" in a production version. | 
 | # | 
 | try: | 
 | 	dummy = cache | 
 | 	del dummy | 
 | except NameError: | 
 | 	cache = {} | 
 |  | 
 |  | 
 | # Clear the entire cache. | 
 | # | 
 | def resetcache(): | 
 | 	for key in cache.keys(): | 
 | 		del cache[key] | 
 |  | 
 |  | 
 | # Clear the node info from the cache (the most voluminous data). | 
 | # | 
 | def resetnodecache(): | 
 | 	for key in cache.keys(): | 
 | 		tags, nodes = cache[key] | 
 | 		cache[key] = tags, {} | 
 |  | 
 |  | 
 | # Get a node. | 
 | # | 
 | def get_node(curfile, ref): | 
 | 	file, node = ifile.parse_ref(curfile, ref) | 
 | 	file = string.lower(file) | 
 | 	node = string.lower(node) | 
 | 	if node == '*': | 
 | 		# Don't cache whole file references; | 
 | 		# reading the data is faster than displaying it anyway. | 
 | 		return ifile.get_whole_file(file) # May raise NoSuchFile | 
 | 	if not cache.has_key(file): | 
 | 		cache[file] = get_tags(file), {} # May raise NoSuchFile | 
 | 	tags, nodes = cache[file] | 
 | 	if not nodes.has_key(node): | 
 | 		if not tags.has_key(node): | 
 | 			raise NoSuchNode, ref | 
 | 		file1, offset, line = tags[node] | 
 | 		if not file1: | 
 | 			file1 = file | 
 | 		file1, node1, header, menu, footnotes, text = \ | 
 | 			ifile.get_file_node(file1, offset, node) | 
 | 		nodes[node] = file, node1, header, menu, footnotes, text | 
 | 	return nodes[node] | 
 |  | 
 |  | 
 | # Get the tag table for a file. | 
 | # Either construct one or get the one found in the file. | 
 | # Raise NoSuchFile if the file isn't found. | 
 | # | 
 | def get_tags(file): | 
 | 	f = ifile.try_open(file) # May raise NoSuchFile | 
 | 	tags = itags.get_tags(f) | 
 | 	if not tags: | 
 | 		###print 'Scanning file...' | 
 | 		f.seek(0) | 
 | 		tags = ifile.make_tags(f) | 
 | 	return tags |