/build/pymake/pymake/util.py

http://github.com/zpao/v8monkey · Python · 150 lines · 107 code · 31 blank · 12 comment · 29 complexity · 33109c645a49c903a611e56441296427 MD5 · raw file

  1. import os
  2. class MakeError(Exception):
  3. def __init__(self, message, loc=None):
  4. self.msg = message
  5. self.loc = loc
  6. def __str__(self):
  7. locstr = ''
  8. if self.loc is not None:
  9. locstr = "%s:" % (self.loc,)
  10. return "%s%s" % (locstr, self.msg)
  11. def normaljoin(path, suffix):
  12. """
  13. Combine the given path with the suffix, and normalize if necessary to shrink the path to avoid hitting path length limits
  14. """
  15. result = os.path.join(path, suffix)
  16. if len(result) > 255:
  17. result = os.path.normpath(result)
  18. return result
  19. def joiniter(fd, it):
  20. """
  21. Given an iterator that returns strings, write the words with a space in between each.
  22. """
  23. it = iter(it)
  24. for i in it:
  25. fd.write(i)
  26. break
  27. for i in it:
  28. fd.write(' ')
  29. fd.write(i)
  30. def checkmsyscompat():
  31. """For msys compatibility on windows, honor the SHELL environment variable,
  32. and if $MSYSTEM == MINGW32, run commands through $SHELL -c instead of
  33. letting Python use the system shell."""
  34. if 'SHELL' in os.environ:
  35. shell = os.environ['SHELL']
  36. elif 'MOZILLABUILD' in os.environ:
  37. shell = os.environ['MOZILLABUILD'] + '/msys/bin/sh.exe'
  38. elif 'COMSPEC' in os.environ:
  39. shell = os.environ['COMSPEC']
  40. else:
  41. raise DataError("Can't find a suitable shell!")
  42. msys = False
  43. if 'MSYSTEM' in os.environ and os.environ['MSYSTEM'] == 'MINGW32':
  44. msys = True
  45. if not shell.lower().endswith(".exe"):
  46. shell += ".exe"
  47. return (shell, msys)
  48. if hasattr(str, 'partition'):
  49. def strpartition(str, token):
  50. return str.partition(token)
  51. def strrpartition(str, token):
  52. return str.rpartition(token)
  53. else:
  54. def strpartition(str, token):
  55. """Python 2.4 compatible str.partition"""
  56. offset = str.find(token)
  57. if offset == -1:
  58. return str, '', ''
  59. return str[:offset], token, str[offset + len(token):]
  60. def strrpartition(str, token):
  61. """Python 2.4 compatible str.rpartition"""
  62. offset = str.rfind(token)
  63. if offset == -1:
  64. return '', '', str
  65. return str[:offset], token, str[offset + len(token):]
  66. try:
  67. from __builtin__ import any
  68. except ImportError:
  69. def any(it):
  70. for i in it:
  71. if i:
  72. return True
  73. return False
  74. class _MostUsedItem(object):
  75. __slots__ = ('key', 'o', 'count')
  76. def __init__(self, key):
  77. self.key = key
  78. self.o = None
  79. self.count = 1
  80. def __repr__(self):
  81. return "MostUsedItem(key=%r, count=%i, o=%r)" % (self.key, self.count, self.o)
  82. class MostUsedCache(object):
  83. def __init__(self, capacity, creationfunc, verifyfunc):
  84. self.capacity = capacity
  85. self.cfunc = creationfunc
  86. self.vfunc = verifyfunc
  87. self.d = {}
  88. self.active = [] # lazily sorted!
  89. def setactive(self, item):
  90. if item in self.active:
  91. return
  92. if len(self.active) == self.capacity:
  93. self.active.sort(key=lambda i: i.count)
  94. old = self.active.pop(0)
  95. old.o = None
  96. # print "Evicting %s" % old.key
  97. self.active.append(item)
  98. def get(self, key):
  99. item = self.d.get(key, None)
  100. if item is None:
  101. item = _MostUsedItem(key)
  102. self.d[key] = item
  103. else:
  104. item.count += 1
  105. if item.o is not None and self.vfunc(key, item.o):
  106. return item.o
  107. item.o = self.cfunc(key)
  108. self.setactive(item)
  109. return item.o
  110. def verify(self):
  111. for k, v in self.d.iteritems():
  112. if v.o:
  113. assert v in self.active
  114. else:
  115. assert v not in self.active
  116. def debugitems(self):
  117. l = [i.key for i in self.active]
  118. l.sort()
  119. return l