import os class MakeError(Exception): def __init__(self, message, loc=None): self.message = message self.loc = loc def __str__(self): locstr = '' if self.loc is not None: locstr = "%s:" % (self.loc,) return "%s%s" % (locstr, self.message) def joiniter(fd, it): """ Given an iterator that returns strings, write the words with a space in between each. """ it = iter(it) for i in it: fd.write(i) break for i in it: fd.write(' ') fd.write(i) def checkmsyscompat(): """For msys compatibility on windows, honor the SHELL environment variable, and if $MSYSTEM == MINGW32, run commands through $SHELL -c instead of letting Python use the system shell.""" if 'SHELL' in os.environ: shell = os.environ['SHELL'] elif 'COMSPEC' in os.environ: shell = os.environ['COMSPEC'] else: raise DataError("Can't find a suitable shell!") msys = False if 'MSYSTEM' in os.environ and os.environ['MSYSTEM'] == 'MINGW32': msys = True if not shell.lower().endswith(".exe"): shell += ".exe" return (shell, msys) if hasattr(str, 'partition'): def strpartition(str, token): return str.partition(token) def strrpartition(str, token): return str.rpartition(token) else: def strpartition(str, token): """Python 2.4 compatible str.partition""" offset = str.find(token) if offset == -1: return str, '', '' return str[:offset], token, str[offset + len(token):] def strrpartition(str, token): """Python 2.4 compatible str.rpartition""" offset = str.rfind(token) if offset == -1: return '', '', str return str[:offset], token, str[offset + len(token):] try: from __builtin__ import any except ImportError: def any(it): for i in it: if i: return True return False class _MostUsedItem(object): __slots__ = ('key', 'o', 'count') def __init__(self, key): self.key = key self.o = None self.count = 1 def __repr__(self): return "MostUsedItem(key=%r, count=%i, o=%r)" % (self.key, self.count, self.o) class MostUsedCache(object): def __init__(self, capacity, creationfunc, verifyfunc): self.capacity = capacity self.cfunc = creationfunc self.vfunc = verifyfunc self.d = {} self.active = [] # lazily sorted! def setactive(self, item): if item in self.active: return if len(self.active) == self.capacity: self.active.sort(key=lambda i: i.count) old = self.active.pop(0) old.o = None # print "Evicting %s" % old.key self.active.append(item) def get(self, key): item = self.d.get(key, None) if item is None: item = _MostUsedItem(key) self.d[key] = item else: item.count += 1 if item.o is not None and self.vfunc(key, item.o): return item.o item.o = self.cfunc(key) self.setactive(item) return item.o def verify(self): for k, v in self.d.iteritems(): if v.o: assert v in self.active else: assert v not in self.active def debugitems(self): l = [i.key for i in self.active] l.sort() return l