home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / EVE_1424_100181.exe / linecache.py < prev    next >
Encoding:
Python Source  |  2004-04-20  |  3.6 KB  |  120 lines

  1. """Cache lines from files.
  2.  
  3. This is intended to read lines from modules imported -- hence if a filename
  4. is not found, it will look down the module search path for a file by
  5. that name.
  6. """
  7.  
  8. import sys
  9. import os
  10. from stat import *
  11.  
  12. __all__ = ["getline","clearcache","checkcache"]
  13.  
  14. def getline(filename, lineno):
  15.     lines = getlines(filename)
  16.     if 1 <= lineno <= len(lines):
  17.         return lines[lineno-1]
  18.     else:
  19.         return ''
  20.  
  21.  
  22. # The cache
  23.  
  24. cache = {} # The cache
  25.  
  26.  
  27. def clearcache():
  28.     """Clear the cache entirely."""
  29.  
  30.     global cache
  31.     cache = {}
  32.  
  33.  
  34. def getlines(filename):
  35.     """Get the lines for a file from the cache.
  36.     Update the cache if it doesn't contain an entry for this file already."""
  37.  
  38.     if cache.has_key(filename):
  39.         return cache[filename][2]
  40.     else:
  41.         return updatecache(filename)
  42.  
  43.  
  44. def checkcache():
  45.     """Discard cache entries that are out of date.
  46.     (This is not checked upon each call!)"""
  47.  
  48.     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
  55.         if size != stat[ST_SIZE] or mtime != stat[ST_MTIME]:
  56.             del cache[filename]
  57.  
  58.  
  59. def updatecache(filename):
  60.  
  61.  
  62.     # NOOOOOO! CCP is very mad at this silly bug.
  63.     # Whenever a stack trace is done, the traceback module uses
  64.     # linecache, which will eventually do an os.stat() call to
  65.     # see if the source file exists on local drive. It's never
  66.     # the case for EVE client as the source code isn't part of
  67.     # the install. The compiled code will contain file references
  68.     # with paths beginning on the drive letter E. If a file access
  69.     # is attempted on drive E:, most WinXP computers will pop up
  70.     # a message box asking the user to insert a disk into the CD
  71.     # drive. This message box is quite annoying, especially in
  72.     # full screen mode where the user simply cannot see the box.
  73.     # The EVE client will do a stack trace once in a while, so
  74.     # this must be fixed here.
  75.     return []
  76.  
  77.  
  78.     """Update a cache entry and return its list of lines.
  79.     If something's wrong, print a message, discard the cache entry,
  80.     and return an empty list."""
  81.  
  82.     if cache.has_key(filename):
  83.         del cache[filename]
  84.     if not filename or filename[0] + filename[-1] == '<>':
  85.         return []
  86.     fullname = filename
  87.     try:
  88.         stat = os.stat(fullname)
  89.     except os.error, msg:
  90.         # Try looking through the module search path.
  91.         basename = os.path.split(filename)[1]
  92.         for dirname in sys.path:
  93.             # When using imputil, sys.path may contain things other than
  94.             # strings; ignore them when it happens.
  95.             try:
  96.                 fullname = os.path.join(dirname, basename)
  97.             except (TypeError, AttributeError):
  98.                 # Not sufficiently string-like to do anything useful with.
  99.                 pass
  100.             else:
  101.                 try:
  102.                     stat = os.stat(fullname)
  103.                     break
  104.                 except os.error:
  105.                     pass
  106.         else:
  107.             # No luck
  108. ##          print '*** Cannot stat', filename, ':', msg
  109.             return []
  110.     try:
  111.         fp = open(fullname, 'r')
  112.         lines = fp.readlines()
  113.         fp.close()
  114.     except IOError, msg:
  115. ##      print '*** Cannot open', fullname, ':', msg
  116.         return []
  117.     size, mtime = stat[ST_SIZE], stat[ST_MTIME]
  118.     cache[filename] = size, mtime, lines, fullname
  119.     return lines
  120.