[2.28] add raptor, used by tracker (GNOME #582754)
[jhbuild.git] / jhbuild / monkeypatch.py
blobb0bded1b217632fb1903f76a8a3f9530169ca76a
1 # jhbuild - a build script for GNOME 1.x and 2.x
2 # Copyright (C) 2001-2006 James Henstridge
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # extras not found in old versions of Python
20 from __future__ import generators
22 import sys
24 # Python < 2.2.1 lacks True and False constants
25 import __builtin__
26 if not hasattr(__builtin__, 'True'):
27 __builtin__.True = (1 == 1)
28 __builtin__.False = (1 != 1)
30 # Python < 2.3 lacks enumerate() builtin
31 if not hasattr(__builtin__, 'enumerate'):
32 def enumerate(iterable):
33 index = 0
34 for item in iterable:
35 yield (index, item)
36 index += 1
37 __builtin__.enumerate = enumerate
39 # Python < 2.3 lacks optparse module
40 try:
41 import optparse
42 except ImportError:
43 from jhbuild.cut_n_paste import optparse
44 sys.modules['optparse'] = optparse
46 # Python < 2.3 lacks locale.getpreferredencoding() function
47 import locale
48 if not hasattr(locale, 'getpreferredencoding'):
49 try:
50 locale.CODESET
51 except NameError:
52 # Fall back to parsing environment variables :-(
53 def getpreferredencoding(do_setlocale = True):
54 """Return the charset that the user is likely using,
55 by looking at environment variables."""
56 return locale.getdefaultlocale()[1]
57 else:
58 def getpreferredencoding(do_setlocale = True):
59 """Return the charset that the user is likely using,
60 according to the system configuration."""
61 if do_setlocale:
62 oldloc = locale.setlocale(locale.LC_CTYPE)
63 locale.setlocale(locale.LC_CTYPE, "")
64 result = locale.nl_langinfo(locale.CODESET)
65 locale.setlocale(locale.LC_CTYPE, oldloc)
66 return result
67 else:
68 return locale.nl_langinfo(locale.CODESET)
70 # Python < 2.4 lacks reversed() builtin
71 if not hasattr(__builtin__, 'reversed'):
72 def reversed(l):
73 l = list(l)
74 l.reverse()
75 return iter(l)
76 __builtin__.reversed = reversed
78 # Python < 2.4 lacks string.Template class
79 import string
80 if not hasattr(string, 'Template'):
81 import re as _re
83 class _multimap:
84 """Helper class for combining multiple mappings.
86 Used by .{safe_,}substitute() to combine the mapping and keyword
87 arguments.
88 """
89 def __init__(self, primary, secondary):
90 self._primary = primary
91 self._secondary = secondary
93 def __getitem__(self, key):
94 try:
95 return self._primary[key]
96 except KeyError:
97 return self._secondary[key]
100 class _TemplateMetaclass(type):
101 pattern = r"""
102 %(delim)s(?:
103 (?P<escaped>%(delim)s) | # Escape sequence of two delimiters
104 (?P<named>%(id)s) | # delimiter and a Python identifier
105 {(?P<braced>%(id)s)} | # delimiter and a braced identifier
106 (?P<invalid>) # Other ill-formed delimiter exprs
110 def __init__(cls, name, bases, dct):
111 super(_TemplateMetaclass, cls).__init__(name, bases, dct)
112 if 'pattern' in dct:
113 pattern = cls.pattern
114 else:
115 pattern = _TemplateMetaclass.pattern % {
116 'delim' : _re.escape(cls.delimiter),
117 'id' : cls.idpattern,
119 cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE)
122 class Template:
123 """A string class for supporting $-substitutions."""
124 __metaclass__ = _TemplateMetaclass
125 __module__ = 'string'
127 delimiter = '$'
128 idpattern = r'[_a-z][_a-z0-9]*'
130 def __init__(self, template):
131 self.template = template
133 # Search for $$, $identifier, ${identifier}, and any bare $'s
135 def _invalid(self, mo):
136 i = mo.start('invalid')
137 lines = self.template[:i].splitlines(True)
138 if not lines:
139 colno = 1
140 lineno = 1
141 else:
142 colno = i - len(''.join(lines[:-1]))
143 lineno = len(lines)
144 raise ValueError(_('Invalid placeholder in string: line %d, col %d') %
145 (lineno, colno))
147 def substitute(self, *args, **kws):
148 if len(args) > 1:
149 raise TypeError(_('Too many positional arguments'))
150 if not args:
151 mapping = kws
152 elif kws:
153 mapping = _multimap(kws, args[0])
154 else:
155 mapping = args[0]
156 # Helper function for .sub()
157 def convert(mo):
158 # Check the most common path first.
159 named = mo.group('named') or mo.group('braced')
160 if named is not None:
161 val = mapping[named]
162 # We use this idiom instead of str() because the latter will
163 # fail if val is a Unicode containing non-ASCII characters.
164 return '%s' % val
165 if mo.group('escaped') is not None:
166 return self.delimiter
167 if mo.group('invalid') is not None:
168 self._invalid(mo)
169 raise ValueError(_('Unrecognized named group in pattern'),
170 self.pattern)
171 return self.pattern.sub(convert, self.template)
173 def safe_substitute(self, *args, **kws):
174 if len(args) > 1:
175 raise TypeError(_('Too many positional arguments'))
176 if not args:
177 mapping = kws
178 elif kws:
179 mapping = _multimap(kws, args[0])
180 else:
181 mapping = args[0]
182 # Helper function for .sub()
183 def convert(mo):
184 named = mo.group('named')
185 if named is not None:
186 try:
187 # We use this idiom instead of str() because the latter
188 # will fail if val is a Unicode containing non-ASCII
189 return '%s' % mapping[named]
190 except KeyError:
191 return self.delimiter + named
192 braced = mo.group('braced')
193 if braced is not None:
194 try:
195 return '%s' % mapping[braced]
196 except KeyError:
197 return self.delimiter + '{' + braced + '}'
198 if mo.group('escaped') is not None:
199 return self.delimiter
200 if mo.group('invalid') is not None:
201 return self.delimiter
202 raise ValueError(_('Unrecognized named group in pattern'),
203 self.pattern)
204 return self.pattern.sub(convert, self.template)
206 string.Template = Template
208 # Python < 2.4 lacks subprocess module
209 try:
210 import subprocess
211 except ImportError:
212 from jhbuild.cut_n_paste import subprocess
213 sys.modules['subprocess'] = subprocess