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 python_type as c_name [for arg_type]
23 # Last ('for') clause is optional. If present, the type will be
24 # imported only if given 'arg_type' is registered.
25 import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)(\s+for\s+(\S+))?')
28 def __init__(self, filename=None):
29 self.modulename = None
31 self.glob_ignores = []
32 self.type_ignores = {}
38 self.staticmethod = {}
41 self.override_attrs = {}
42 self.override_slots = {}
49 self.newstyle_constructors = {}
50 self.dynamicnamespace = False
52 self.handle_file(filename)
54 def handle_file(self, filename):
57 fp = open(filename, 'r')
58 dirname = os.path.dirname(os.path.abspath(filename))
60 if dirname != oldpath:
63 # read all the components of the file ...
70 if line == '%%\n' or line == '%%':
72 bufs.append((string.join(lines, ''), startline))
73 startline = linenum + 1
80 bufs.append((string.join(lines, ''), startline))
83 for buf, startline in bufs:
84 self.__parse_override(buf, startline, filename)
88 def __parse_override(self, buffer, startline, filename):
89 pos = string.find(buffer, '\n')
94 line = buffer ; rest = ''
95 words = string.split(line)
97 if (command == 'ignore' or
98 command == 'ignore-' + sys.platform):
99 "ignore/ignore-platform [functions..]"
100 for func in words[1:]:
101 self.ignores[func] = 1
102 for func in string.split(rest):
103 self.ignores[func] = 1
104 elif (command == 'ignore-glob' or
105 command == 'ignore-glob-' + sys.platform):
106 "ignore-glob/ignore-glob-platform [globs..]"
107 for func in words[1:]:
108 self.glob_ignores.append(func)
109 for func in string.split(rest):
110 self.glob_ignores.append(func)
111 elif (command == 'ignore-type' or
112 command == 'ignore-type-' + sys.platform):
113 "ignore-type/ignore-type-platform [typenames..]"
114 for typename in words[1:]:
115 self.type_ignores[typename] = 1
116 for typename in string.split(rest):
117 self.type_ignores[typename] = 1
118 elif command == 'override':
119 "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
121 if 'kwargs' in words[1:]:
122 self.kwargs[func] = 1
123 elif 'noargs' in words[1:]:
124 self.noargs[func] = 1
125 elif 'onearg' in words[1:]:
126 self.onearg[func] = True
128 if 'staticmethod' in words[1:]:
129 self.staticmethod[func] = True
130 elif 'classmethod' in words[1:]:
131 self.classmethod[func] = True
132 if func in self.overrides:
133 raise RuntimeError("Function %s is being overridden more than once" % (func,))
134 self.overrides[func] = rest
135 self.startlines[func] = (startline + 1, filename)
136 elif command == 'override-attr':
137 "override-slot Class.attr"
139 self.override_attrs[attr] = rest
140 self.startlines[attr] = (startline + 1, filename)
141 elif command == 'override-slot':
142 "override-slot Class.slot"
144 self.override_slots[slot] = rest
145 self.startlines[slot] = (startline + 1, filename)
146 elif command == 'headers':
148 self.headers = '%s\n#line %d "%s"\n%s' % \
149 (self.headers, startline + 1, filename, rest)
150 elif command == 'body':
152 self.body = '%s\n#line %d "%s"\n%s' % \
153 (self.body, startline + 1, filename, rest)
154 elif command == 'init':
156 self.init = '%s\n#line %d "%s"\n%s' % \
157 (self.init, startline + 1, filename, rest)
158 elif command == 'modulename':
160 self.modulename = words[1]
161 elif command == 'include':
163 for filename in words[1:]:
164 self.handle_file(filename)
165 for filename in string.split(rest):
166 self.handle_file(filename)
167 elif command == 'import':
168 "import module1 [\n module2, \n module3 ...]"
169 for line in string.split(buffer, '\n'):
170 match = import_pat.match(line)
172 module, pyname, cname, conditional, importing_for = match.groups()
173 self.imports.append((module, pyname, cname, importing_for or None))
174 elif command == 'define':
175 "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
176 "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
179 if func.find('.') != -1:
180 klass, func = func.split('.', 1)
182 if not self.defines.has_key(klass):
183 self.defines[klass] = {}
184 self.defines[klass][func] = rest
186 self.functions[func] = rest
188 if 'kwargs' in words[1:]:
189 self.kwargs[func] = 1
190 elif 'noargs' in words[1:]:
191 self.noargs[func] = 1
192 elif 'onearg' in words[1:]:
193 self.onearg[func] = 1
195 if 'staticmethod' in words[1:]:
196 self.staticmethod[func] = True
197 elif 'classmethod' in words[1:]:
198 self.classmethod[func] = True
200 self.startlines[func] = (startline + 1, filename)
202 elif command == 'new-constructor':
203 "new-constructor GType"
205 self.newstyle_constructors[gtype] = True
206 elif command == 'options':
207 for option in words[1:]:
208 if option == 'dynamicnamespace':
209 self.dynamicnamespace = True
211 def is_ignored(self, name):
212 if self.ignores.has_key(name):
214 for glob in self.glob_ignores:
215 if fnmatch.fnmatchcase(name, glob):
219 def is_type_ignored(self, name):
220 return name in self.type_ignores
222 def is_overriden(self, name):
223 return self.overrides.has_key(name)
225 def is_already_included(self, name):
226 return self.overridden.has_key(name)
228 def override(self, name):
229 self.overridden[name] = 1
230 return self.overrides[name]
232 def define(self, klass, name):
233 self.overridden[class2cname(klass, name)] = 1
234 return self.defines[klass][name]
236 def function(self, name):
237 return self.functions[name]
239 def getstartline(self, name):
240 return self.startlines[name]
242 def wants_kwargs(self, name):
243 return self.kwargs.has_key(name)
245 def wants_noargs(self, name):
246 return self.noargs.has_key(name)
248 def wants_onearg(self, name):
249 return self.onearg.has_key(name)
251 def is_staticmethod(self, name):
252 return self.staticmethod.has_key(name)
254 def is_classmethod(self, name):
255 return self.classmethod.has_key(name)
257 def attr_is_overriden(self, attr):
258 return self.override_attrs.has_key(attr)
260 def attr_override(self, attr):
261 return self.override_attrs[attr]
263 def slot_is_overriden(self, slot):
264 return self.override_slots.has_key(slot)
266 def slot_override(self, slot):
267 return self.override_slots[slot]
269 def get_headers(self):
278 def get_imports(self):
281 def get_defines_for(self, klass):
282 return self.defines.get(klass, {})
284 def get_functions(self):
285 return self.functions