1 # -*- Mode: Python; py-indent-offset: 4 -*-
3 # this file contains code for loading up an override file. The override file
4 # provides implementations of functions where the code generator could not
5 # do its job correctly.
13 def class2cname(klass, method):
17 c_name += '_' + c.lower()
20 return c_name[1:] + '_' + method
22 import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)')
25 def __init__(self, filename=None, path=[]):
26 self.modulename = None
28 self.glob_ignores = []
29 self.type_ignores = {}
35 self.staticmethod = {}
38 self.override_attrs = {}
39 self.override_slots = {}
46 self.newstyle_constructors = {}
47 self.path = [os.path.abspath(x) for x in path]
49 self.handle_file(filename)
51 def handle_file(self, filename):
55 for path in self.path:
59 fp = open(filename, 'r')
64 raise Exception, "Couldn't find file %s" % filename
68 if dirname != oldpath:
71 # read all the components of the file ...
78 if line == '%%\n' or line == '%%':
80 bufs.append((string.join(lines, ''), startline))
81 startline = linenum + 1
88 bufs.append((string.join(lines, ''), startline))
91 for buf, startline in bufs:
92 self.__parse_override(buf, startline, filename)
96 def __parse_override(self, buffer, startline, filename):
97 pos = string.find(buffer, '\n')
100 rest = buffer[pos+1:]
102 line = buffer ; rest = ''
103 words = string.split(line)
105 if (command == 'ignore' or
106 command == 'ignore-' + sys.platform):
107 "ignore/ignore-platform [functions..]"
108 for func in words[1:]:
109 self.ignores[func] = 1
110 for func in string.split(rest):
111 self.ignores[func] = 1
112 elif (command == 'ignore-glob' or
113 command == 'ignore-glob-' + sys.platform):
114 "ignore-glob/ignore-glob-platform [globs..]"
115 for func in words[1:]:
116 self.glob_ignores.append(func)
117 for func in string.split(rest):
118 self.glob_ignores.append(func)
119 elif (command == 'ignore-type' or
120 command == 'ignore-type-' + sys.platform):
121 "ignore-type/ignore-type-platform [typenames..]"
122 for typename in words[1:]:
123 self.type_ignores[typename] = 1
124 for typename in string.split(rest):
125 self.type_ignores[typename] = 1
126 elif command == 'override':
127 "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
129 if 'kwargs' in words[1:]:
130 self.kwargs[func] = 1
131 elif 'noargs' in words[1:]:
132 self.noargs[func] = 1
133 elif 'onearg' in words[1:]:
134 self.onearg[func] = True
136 if 'staticmethod' in words[1:]:
137 self.staticmethod[func] = True
138 elif 'classmethod' in words[1:]:
139 self.classmethod[func] = True
140 if func in self.overrides:
141 raise RuntimeError("Function %s is being overridden more than once" % (func,))
142 self.overrides[func] = rest
143 self.startlines[func] = (startline + 1, filename)
144 elif command == 'override-attr':
145 "override-slot Class.attr"
147 self.override_attrs[attr] = rest
148 self.startlines[attr] = (startline + 1, filename)
149 elif command == 'override-slot':
150 "override-slot Class.slot"
152 self.override_slots[slot] = rest
153 self.startlines[slot] = (startline + 1, filename)
154 elif command == 'headers':
156 self.headers = '%s\n#line %d "%s"\n%s' % \
157 (self.headers, startline + 1, filename, rest)
158 elif command == 'body':
160 self.body = '%s\n#line %d "%s"\n%s' % \
161 (self.body, startline + 1, filename, rest)
162 elif command == 'init':
164 self.init = '%s\n#line %d "%s"\n%s' % \
165 (self.init, startline + 1, filename, rest)
166 elif command == 'modulename':
168 self.modulename = words[1]
169 elif command == 'include':
171 for filename in words[1:]:
172 self.handle_file(filename)
173 for filename in string.split(rest):
174 self.handle_file(filename)
175 elif command == 'import':
176 "import module1 [\n module2, \n module3 ...]"
177 for line in string.split(buffer, '\n'):
178 match = import_pat.match(line)
180 self.imports.append(match.groups())
181 elif command == 'define':
182 "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
183 "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
186 if func.find('.') != -1:
187 klass, func = func.split('.', 1)
189 if not self.defines.has_key(klass):
190 self.defines[klass] = {}
191 self.defines[klass][func] = rest
193 self.functions[func] = rest
195 if 'kwargs' in words[1:]:
196 self.kwargs[func] = 1
197 elif 'noargs' in words[1:]:
198 self.noargs[func] = 1
199 elif 'onearg' in words[1:]:
200 self.onearg[func] = 1
202 if 'staticmethod' in words[1:]:
203 self.staticmethod[func] = True
204 elif 'classmethod' in words[1:]:
205 self.classmethod[func] = True
207 self.startlines[func] = (startline + 1, filename)
209 elif command == 'new-constructor':
210 "new-constructor GType"
212 self.newstyle_constructors[gtype] = True
214 def is_ignored(self, name):
215 if self.ignores.has_key(name):
217 for glob in self.glob_ignores:
218 if fnmatch.fnmatchcase(name, glob):
222 def is_type_ignored(self, name):
223 return name in self.type_ignores
225 def is_overriden(self, name):
226 return self.overrides.has_key(name)
228 def is_already_included(self, name):
229 return self.overridden.has_key(name)
231 def override(self, name):
232 self.overridden[name] = 1
233 return self.overrides[name]
235 def define(self, klass, name):
236 self.overridden[class2cname(klass, name)] = 1
237 return self.defines[klass][name]
239 def function(self, name):
240 return self.functions[name]
242 def getstartline(self, name):
243 return self.startlines[name]
245 def wants_kwargs(self, name):
246 return self.kwargs.has_key(name)
248 def wants_noargs(self, name):
249 return self.noargs.has_key(name)
251 def wants_onearg(self, name):
252 return self.onearg.has_key(name)
254 def is_staticmethod(self, name):
255 return self.staticmethod.has_key(name)
257 def is_classmethod(self, name):
258 return self.classmethod.has_key(name)
260 def attr_is_overriden(self, attr):
261 return self.override_attrs.has_key(attr)
263 def attr_override(self, attr):
264 return self.override_attrs[attr]
266 def slot_is_overriden(self, slot):
267 return self.override_slots.has_key(slot)
269 def slot_override(self, slot):
270 return self.override_slots[slot]
272 def get_headers(self):
281 def get_imports(self):
284 def get_defines_for(self, klass):
285 return self.defines.get(klass, {})
287 def get_functions(self):
288 return self.functions