mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
93fd2d4f43
Without this, having an empty line in an override will cause codegen to unceremoniously choke to death. https://bugzilla.gnome.org/show_bug.cgi?id=640341
290 lines
9.2 KiB
Python
290 lines
9.2 KiB
Python
# -*- Mode: Python; py-indent-offset: 4 -*-
|
|
|
|
# this file contains code for loading up an override file. The override file
|
|
# provides implementations of functions where the code generator could not
|
|
# do its job correctly.
|
|
|
|
import fnmatch
|
|
import os
|
|
import re
|
|
import string
|
|
import sys
|
|
|
|
def class2cname(klass, method):
|
|
c_name = ''
|
|
for c in klass:
|
|
if c.isupper():
|
|
c_name += '_' + c.lower()
|
|
else:
|
|
c_name += c
|
|
return c_name[1:] + '_' + method
|
|
|
|
import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)')
|
|
|
|
class Overrides:
|
|
def __init__(self, filename=None, path=[]):
|
|
self.modulename = None
|
|
self.ignores = {}
|
|
self.glob_ignores = []
|
|
self.type_ignores = {}
|
|
self.overrides = {}
|
|
self.overridden = {}
|
|
self.kwargs = {}
|
|
self.noargs = {}
|
|
self.onearg = {}
|
|
self.staticmethod = {}
|
|
self.classmethod = {}
|
|
self.startlines = {}
|
|
self.override_attrs = {}
|
|
self.override_slots = {}
|
|
self.headers = ''
|
|
self.body = ''
|
|
self.init = ''
|
|
self.imports = []
|
|
self.defines = {}
|
|
self.functions = {}
|
|
self.newstyle_constructors = {}
|
|
self.path = [os.path.abspath(x) for x in path]
|
|
if filename:
|
|
self.handle_file(filename)
|
|
|
|
def handle_file(self, filename):
|
|
oldpath = os.getcwd()
|
|
|
|
fp = None
|
|
for path in self.path:
|
|
os.chdir(oldpath)
|
|
os.chdir(path)
|
|
try:
|
|
fp = open(filename, 'r')
|
|
break
|
|
except:
|
|
os.chdir(oldpath)
|
|
if not fp:
|
|
raise Exception, "Couldn't find file %s" % filename
|
|
|
|
dirname = path
|
|
|
|
if dirname != oldpath:
|
|
os.chdir(dirname)
|
|
|
|
# read all the components of the file ...
|
|
bufs = []
|
|
startline = 1
|
|
lines = []
|
|
line = fp.readline()
|
|
linenum = 1
|
|
while line:
|
|
if line == '%%\n' or line == '%%':
|
|
if lines:
|
|
bufs.append((string.join(lines, ''), startline))
|
|
startline = linenum + 1
|
|
lines = []
|
|
else:
|
|
lines.append(line)
|
|
line = fp.readline()
|
|
linenum = linenum + 1
|
|
if lines:
|
|
bufs.append((string.join(lines, ''), startline))
|
|
if not bufs: return
|
|
|
|
for buf, startline in bufs:
|
|
self.__parse_override(buf, startline, filename)
|
|
|
|
os.chdir(oldpath)
|
|
|
|
def __parse_override(self, buffer, startline, filename):
|
|
pos = string.find(buffer, '\n')
|
|
if pos >= 0:
|
|
line = buffer[:pos]
|
|
rest = buffer[pos+1:]
|
|
else:
|
|
line = buffer ; rest = ''
|
|
words = string.split(line)
|
|
if len(words) == 0:
|
|
return
|
|
command = words[0]
|
|
if (command == 'ignore' or
|
|
command == 'ignore-' + sys.platform):
|
|
"ignore/ignore-platform [functions..]"
|
|
for func in words[1:]:
|
|
self.ignores[func] = 1
|
|
for func in string.split(rest):
|
|
self.ignores[func] = 1
|
|
elif (command == 'ignore-glob' or
|
|
command == 'ignore-glob-' + sys.platform):
|
|
"ignore-glob/ignore-glob-platform [globs..]"
|
|
for func in words[1:]:
|
|
self.glob_ignores.append(func)
|
|
for func in string.split(rest):
|
|
self.glob_ignores.append(func)
|
|
elif (command == 'ignore-type' or
|
|
command == 'ignore-type-' + sys.platform):
|
|
"ignore-type/ignore-type-platform [typenames..]"
|
|
for typename in words[1:]:
|
|
self.type_ignores[typename] = 1
|
|
for typename in string.split(rest):
|
|
self.type_ignores[typename] = 1
|
|
elif command == 'override':
|
|
"override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
|
|
func = words[1]
|
|
if 'kwargs' in words[1:]:
|
|
self.kwargs[func] = 1
|
|
elif 'noargs' in words[1:]:
|
|
self.noargs[func] = 1
|
|
elif 'onearg' in words[1:]:
|
|
self.onearg[func] = True
|
|
|
|
if 'staticmethod' in words[1:]:
|
|
self.staticmethod[func] = True
|
|
elif 'classmethod' in words[1:]:
|
|
self.classmethod[func] = True
|
|
if func in self.overrides:
|
|
raise RuntimeError("Function %s is being overridden more than once" % (func,))
|
|
self.overrides[func] = rest
|
|
self.startlines[func] = (startline + 1, filename)
|
|
elif command == 'override-attr':
|
|
"override-slot Class.attr"
|
|
attr = words[1]
|
|
self.override_attrs[attr] = rest
|
|
self.startlines[attr] = (startline + 1, filename)
|
|
elif command == 'override-slot':
|
|
"override-slot Class.slot"
|
|
slot = words[1]
|
|
self.override_slots[slot] = rest
|
|
self.startlines[slot] = (startline + 1, filename)
|
|
elif command == 'headers':
|
|
"headers"
|
|
self.headers = '%s\n#line %d "%s"\n%s' % \
|
|
(self.headers, startline + 1, filename, rest)
|
|
elif command == 'body':
|
|
"body"
|
|
self.body = '%s\n#line %d "%s"\n%s' % \
|
|
(self.body, startline + 1, filename, rest)
|
|
elif command == 'init':
|
|
"init"
|
|
self.init = '%s\n#line %d "%s"\n%s' % \
|
|
(self.init, startline + 1, filename, rest)
|
|
elif command == 'modulename':
|
|
"modulename name"
|
|
self.modulename = words[1]
|
|
elif command == 'include':
|
|
"include filename"
|
|
for filename in words[1:]:
|
|
self.handle_file(filename)
|
|
for filename in string.split(rest):
|
|
self.handle_file(filename)
|
|
elif command == 'import':
|
|
"import module1 [\n module2, \n module3 ...]"
|
|
for line in string.split(buffer, '\n'):
|
|
match = import_pat.match(line)
|
|
if match:
|
|
self.imports.append(match.groups())
|
|
elif command == 'define':
|
|
"define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
|
|
"define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
|
|
func = words[1]
|
|
klass = None
|
|
if func.find('.') != -1:
|
|
klass, func = func.split('.', 1)
|
|
|
|
if not self.defines.has_key(klass):
|
|
self.defines[klass] = {}
|
|
self.defines[klass][func] = rest
|
|
else:
|
|
self.functions[func] = rest
|
|
|
|
if 'kwargs' in words[1:]:
|
|
self.kwargs[func] = 1
|
|
elif 'noargs' in words[1:]:
|
|
self.noargs[func] = 1
|
|
elif 'onearg' in words[1:]:
|
|
self.onearg[func] = 1
|
|
|
|
if 'staticmethod' in words[1:]:
|
|
self.staticmethod[func] = True
|
|
elif 'classmethod' in words[1:]:
|
|
self.classmethod[func] = True
|
|
|
|
self.startlines[func] = (startline + 1, filename)
|
|
|
|
elif command == 'new-constructor':
|
|
"new-constructor GType"
|
|
gtype, = words[1:]
|
|
self.newstyle_constructors[gtype] = True
|
|
|
|
def is_ignored(self, name):
|
|
if self.ignores.has_key(name):
|
|
return 1
|
|
for glob in self.glob_ignores:
|
|
if fnmatch.fnmatchcase(name, glob):
|
|
return 1
|
|
return 0
|
|
|
|
def is_type_ignored(self, name):
|
|
return name.rstrip('*') in self.type_ignores
|
|
|
|
def is_overriden(self, name):
|
|
return self.overrides.has_key(name)
|
|
|
|
def is_already_included(self, name):
|
|
return self.overridden.has_key(name)
|
|
|
|
def override(self, name):
|
|
self.overridden[name] = 1
|
|
return self.overrides[name]
|
|
|
|
def define(self, klass, name):
|
|
self.overridden[class2cname(klass, name)] = 1
|
|
return self.defines[klass][name]
|
|
|
|
def function(self, name):
|
|
return self.functions[name]
|
|
|
|
def getstartline(self, name):
|
|
return self.startlines[name]
|
|
|
|
def wants_kwargs(self, name):
|
|
return self.kwargs.has_key(name)
|
|
|
|
def wants_noargs(self, name):
|
|
return self.noargs.has_key(name)
|
|
|
|
def wants_onearg(self, name):
|
|
return self.onearg.has_key(name)
|
|
|
|
def is_staticmethod(self, name):
|
|
return self.staticmethod.has_key(name)
|
|
|
|
def is_classmethod(self, name):
|
|
return self.classmethod.has_key(name)
|
|
|
|
def attr_is_overriden(self, attr):
|
|
return self.override_attrs.has_key(attr)
|
|
|
|
def attr_override(self, attr):
|
|
return self.override_attrs[attr]
|
|
|
|
def slot_is_overriden(self, slot):
|
|
return self.override_slots.has_key(slot)
|
|
|
|
def slot_override(self, slot):
|
|
return self.override_slots[slot]
|
|
|
|
def get_headers(self):
|
|
return self.headers
|
|
|
|
def get_body(self):
|
|
return self.body
|
|
|
|
def get_init(self):
|
|
return self.init
|
|
|
|
def get_imports(self):
|
|
return self.imports
|
|
|
|
def get_defines_for(self, klass):
|
|
return self.defines.get(klass, {})
|
|
|
|
def get_functions(self):
|
|
return self.functions
|