diff options
Diffstat (limited to 'build/pymake/pymake/util.py')
-rw-r--r-- | build/pymake/pymake/util.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/build/pymake/pymake/util.py b/build/pymake/pymake/util.py new file mode 100644 index 000000000..c63f930cc --- /dev/null +++ b/build/pymake/pymake/util.py @@ -0,0 +1,150 @@ +import os + +class MakeError(Exception): + def __init__(self, message, loc=None): + self.msg = message + self.loc = loc + + def __str__(self): + locstr = '' + if self.loc is not None: + locstr = "%s:" % (self.loc,) + + return "%s%s" % (locstr, self.msg) + +def normaljoin(path, suffix): + """ + Combine the given path with the suffix, and normalize if necessary to shrink the path to avoid hitting path length limits + """ + result = os.path.join(path, suffix) + if len(result) > 255: + result = os.path.normpath(result) + return result + +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 'MOZILLABUILD' in os.environ: + shell = os.environ['MOZILLABUILD'] + '/msys/bin/sh.exe' + 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 |