blob: cd3e50d27edde9e426fffe1e70a4554d013c6126 [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Cache lines from files.
2
3This is intended to read lines from modules imported -- hence if a filename
4is not found, it will look down the module search path for a file by
5that name.
6"""
Guido van Rossum921c8241992-01-10 14:54:42 +00007
Guido van Rossumc341c621992-03-27 15:12:43 +00008import sys
Guido van Rossum921c8241992-01-10 14:54:42 +00009import os
10from stat import *
11
Skip Montanaro17ab1232001-01-24 06:27:27 +000012__all__ = ["getline","clearcache","checkcache"]
13
Guido van Rossum921c8241992-01-10 14:54:42 +000014def getline(filename, lineno):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000015 lines = getlines(filename)
16 if 1 <= lineno <= len(lines):
17 return lines[lineno-1]
18 else:
19 return ''
Guido van Rossum921c8241992-01-10 14:54:42 +000020
21
22# The cache
23
24cache = {} # The cache
25
26
Guido van Rossum921c8241992-01-10 14:54:42 +000027def clearcache():
Guido van Rossum54f22ed2000-02-04 15:10:34 +000028 """Clear the cache entirely."""
Guido van Rossum921c8241992-01-10 14:54:42 +000029
Guido van Rossum54f22ed2000-02-04 15:10:34 +000030 global cache
31 cache = {}
Guido van Rossum921c8241992-01-10 14:54:42 +000032
Guido van Rossum921c8241992-01-10 14:54:42 +000033
34def getlines(filename):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000035 """Get the lines for a file from the cache.
36 Update the cache if it doesn't contain an entry for this file already."""
Guido van Rossum921c8241992-01-10 14:54:42 +000037
Guido van Rossum54f22ed2000-02-04 15:10:34 +000038 if cache.has_key(filename):
39 return cache[filename][2]
40 else:
41 return updatecache(filename)
Guido van Rossum921c8241992-01-10 14:54:42 +000042
Guido van Rossum921c8241992-01-10 14:54:42 +000043
44def checkcache():
Guido van Rossum54f22ed2000-02-04 15:10:34 +000045 """Discard cache entries that are out of date.
46 (This is not checked upon each call!)"""
Guido van Rossum921c8241992-01-10 14:54:42 +000047
Guido van Rossum54f22ed2000-02-04 15:10:34 +000048 for filename in cache.keys():
49 size, mtime, lines, fullname = cache[filename]
50 try:
51 stat = os.stat(fullname)
52 except os.error:
53 del cache[filename]
54 continue
Fred Drake8152d322000-12-12 23:20:45 +000055 if size != stat[ST_SIZE] or mtime != stat[ST_MTIME]:
Guido van Rossum54f22ed2000-02-04 15:10:34 +000056 del cache[filename]
Guido van Rossum921c8241992-01-10 14:54:42 +000057
Guido van Rossum921c8241992-01-10 14:54:42 +000058
59def updatecache(filename):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000060 """Update a cache entry and return its list of lines.
61 If something's wrong, print a message, discard the cache entry,
62 and return an empty list."""
63
64 if cache.has_key(filename):
65 del cache[filename]
66 if not filename or filename[0] + filename[-1] == '<>':
67 return []
68 fullname = filename
69 try:
70 stat = os.stat(fullname)
71 except os.error, msg:
Tim Peters12f21ae2001-05-29 04:27:01 +000072 # Try looking through the module search path.
Guido van Rossum54f22ed2000-02-04 15:10:34 +000073 basename = os.path.split(filename)[1]
74 for dirname in sys.path:
Tim Peters12f21ae2001-05-29 04:27:01 +000075 # When using imputil, sys.path may contain things other than
76 # strings; ignore them when it happens.
Guido van Rossum54f22ed2000-02-04 15:10:34 +000077 try:
Tim Peters12f21ae2001-05-29 04:27:01 +000078 fullname = os.path.join(dirname, basename)
79 except (TypeError, AttributeError):
80 # Not sufficiently string-like to do anything useful with.
Guido van Rossum54f22ed2000-02-04 15:10:34 +000081 pass
Tim Peters12f21ae2001-05-29 04:27:01 +000082 else:
83 try:
84 stat = os.stat(fullname)
85 break
86 except os.error:
87 pass
Guido van Rossum54f22ed2000-02-04 15:10:34 +000088 else:
89 # No luck
90## print '*** Cannot stat', filename, ':', msg
91 return []
92 try:
93 fp = open(fullname, 'r')
94 lines = fp.readlines()
95 fp.close()
96 except IOError, msg:
97## print '*** Cannot open', fullname, ':', msg
98 return []
99 size, mtime = stat[ST_SIZE], stat[ST_MTIME]
100 cache[filename] = size, mtime, lines, fullname
101 return lines